import { sys } from "cc"; import { EGlobalEvent } from "../../MesEvent/EGlobalEvent"; import MesMgr from "../../MesEvent/MesMgr"; import { GEData } from "../../Mgr_Ge/GeDifine"; import { TDAnalyticsMgr } from "../../Mgr_Ge/TDAnalyticsMgr"; import LocalStorage from "../../Mgr_LocalData/LocalStorage"; import PlatformData from "../Data/PlatformData"; import { PlatformEnum_TT } from "../Data/PlatformEnum"; import TTDevice from "../Device/TTDevice"; import TTRecordManager from "../Record/TTRecordManager"; import ShareManagerAKhgfawgsda from "../ShareManager"; import { EPlatformType } from "../T/EPlatformType"; import { IDevice } from "../T/IDevice"; import IRecordManager from "../T/IRecordManager"; import { ShareInfo } from "../T/ShareInfo"; import WXPlatform from "./WXPlatform"; import { PlatformCommonDefine } from "../Common/PlatformCommonDefine"; import PlatformManagerProxy from "../PlatformManagerProxy"; import { MainConfig } from "db://assets/Launch/_MainConfig"; import PlatformManager from "../PlatformManager"; /** * 头条平台实例 */ export default class TTPlatform extends WXPlatform { IsLeaderboardsEnable: boolean=false; platform: EPlatformType = EPlatformType.TT; protected _showVideoLoad: boolean = true; recordManager: IRecordManager; protected openIDUrl:string = "https://game-api.lvzhouyouxi.com/getOpenId_line_dy"; Init(platformData: PlatformData,callBack:Function) { this.isAddShortcut = true; this._base = window["tt"] //= window["wx"]; if (this._base == null) { console.warn("平台初始化错误"); return; } this.platformData = platformData; // 检测是否支持交叉推广 let tt = this._base; let systemInfo = tt.getSystemInfoSync(); if (systemInfo.platform == "ios") { this.isSupportJumpOther = false; } let [major, minor] = systemInfo.SDKVersion.split("."); if (major >= 1 && minor >= 33) { } else { this.isSupportJumpOther = false; } switch (this.platformData.appId) { default: break; } // 监听 Feed 流进入/退出小游戏事件 tt.onFeedStatusChange(({ type }) => { if (type === 'feedEnter') { ConsoleEx.Warn('触发从Feed流进入小游戏事件回调') MainConfig.isFeedEnter = true; // 如果是获客方式正式进入,则发送一条时间,显示被隐藏的功能入口 // ConsoleEx.Warn("!!!!!!!!!!发送EGlobalEvent.E_FEED_ENTER_GAME,进入游戏"); MesMgr.event(EGlobalEvent.E_FEED_ENTER_GAME); } if (type === 'feedExit') { ConsoleEx.Warn('触发从小游戏退回到Feed流事件回调') MainConfig.isFeedEnter = false; // 如果是获客方式正式进入,则发送一条时间,显示被隐藏的功能入口 // ConsoleEx.Warn("!!!!!!!!!!发送EGlobalEvent.E_FEED_ENTER_GAME,退出游戏"); MesMgr.event(EGlobalEvent.E_FEED_ENTER_GAME); } }); this._InitLauchOption(); this._Login(callBack); this._InitShareInfo(); this._InitSystemInfo(); this._CreateBannerAd(); this._CreateVideoAd(); this._CreateInterstitalAd(); this.checkShortcut((isOK)=>{this.isAddShortcut = isOK}); this.recordManager = new TTRecordManager(this._base); this.recordManager.Platform = this; this._base.onShow((res) => { console.log("启动参数:", res.query); console.log("来源信息:", res.refererInfo); console.log("场景值:", res.scene); console.log("启动场景字段:", res.launch_from, ", ", res.location); if (res.launch_from == 'homepage' && res.location == 'sidebar_card') { console.log('从侧边栏启动') window["cebianlan"] = true; MesMgr.event(EGlobalEvent.E_CHECK_CEBIAN_LAN); } }); window["iplatform"] = this; } oceanengineEvent() { super.oceanengineEvent(); this.keep3DayEvent(); this.keep7DayEvent(); } // -------------------- 巨量回传次留-七留 -------------------- // 3日留存 public keep3DayEvent() { // 获取激活时间 const activationDateStr = LocalStorage.getItem('activationDate') // const clickId = GameManager.getInstance().getClickID(); // 检查是否有激活时间和clickId if (!activationDateStr) { console.log("未找到激活时间,不上报3日留存"); return; } // 检查是否已经上报过3日留存 //@ts-ignore const hasReported3DayKeep = LocalStorage.getItem('hasReported3DayKeep'); if (hasReported3DayKeep) { console.log("3日留存已经上报过,不再上报"); return; } if (!this.clickId) { console.log("无 clickid,不上报3日留存"); return; } const activationDate = new Date(activationDateStr); const currentDate = new Date(); // 计算日期差 const activationDay = new Date(activationDate.getFullYear(), activationDate.getMonth(), activationDate.getDate()); const currentDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()); // 计算两个日期之间的天数差 const diffTime = currentDay.getTime() - activationDay.getTime(); const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24)); // 只有当是激活后的第三天(diffDays === 3)才上报3日留存 if (diffDays !== 3) { console.log(`不是激活后的第三天(差值: ${diffDays}天),不上报3日留存`); return; } console.log("满足3日留存条件,准备上报"); const url = 'https://analytics.oceanengine.com/api/v2/conversion'; const data = { event_type: 'retention_3d', context: { ad: { callback: this.clickId, // 广告 clickid } }, timestamp: currentDate.getTime() }; console.log("上报数据:", data); // @ts-ignore tt.request({ url, method: "POST", data: JSON.stringify(data), header: { "Content-Type": "application/json" }, success: (res) => { console.log("广告归因上报成功:", res); // 标记已上报3日留存,避免重复上报 //@ts-ignore LocalStorage.setItem('hasReported3DayKeep', 'true'); }, fail: (err) => { console.error("广告归因上报失败:", err); } }); } // 7日留存 public keep7DayEvent() { // 获取激活时间 const activationDateStr = LocalStorage.getItem('activationDate') // const clickId = GameManager.getInstance().getClickID(); // 检查是否有激活时间和clickId if (!activationDateStr) { console.log("未找到激活时间,不上报7日留存"); return; } // 检查是否已经上报过7日留存 //@ts-ignore const hasReported7DayKeep = LocalStorage.getItem('hasReported7DayKeep'); if (hasReported7DayKeep) { console.log("7日留存已经上报过,不再上报"); return; } if (!this.clickId) { console.log("无 clickid,不上报7日留存"); return; } const activationDate = new Date(activationDateStr); const currentDate = new Date(); // 计算日期差 const activationDay = new Date(activationDate.getFullYear(), activationDate.getMonth(), activationDate.getDate()); const currentDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()); // 计算两个日期之间的天数差 const diffTime = currentDay.getTime() - activationDay.getTime(); const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24)); // 只有当是激活后的第七天(diffDays === 7)才上报7日留存 if (diffDays !== 7) { console.log(`不是激活后的第七天(差值: ${diffDays}天),不上报7日留存`); return; } console.log("满足7日留存条件,准备上报"); const url = 'https://analytics.oceanengine.com/api/v2/conversion'; const data = { event_type: 'retention_7d', context: { ad: { callback: this.clickId, // 广告 clickid } }, timestamp: currentDate.getTime() }; console.log("上报数据:", data); // @ts-ignore tt.request({ url, method: "POST", data: JSON.stringify(data), header: { "Content-Type": "application/json" }, success: (res) => { console.log("广告归因上报成功:", res); // 标记已上报7日留存,避免重复上报 //@ts-ignore LocalStorage.setItem('hasReported7DayKeep', 'true'); }, fail: (err) => { console.error("广告归因上报失败:", err); } }); } protected _CreateVideoAd() { console.log('vedio ad id', this.platformData.rewardVideoId) if (!this._cacheVideoAD) { console.log("当前策略为不缓存视频广告"); return; } let createRewardedVideoAd = this._base["createRewardedVideoAd"]; if (createRewardedVideoAd == null) { console.warn("无createRewardedVideoAd方法,跳过初始化"); return; } if (!this.platformData.rewardVideoId) { console.log("无有效的视频广告ID,取消加载"); return; } this._videoFailedCount = 0; let videoObj = {}; videoObj["adUnitId"] = this.platformData.rewardVideoId; this._rewardVideo = createRewardedVideoAd(videoObj); this._rewardVideo.onLoad(() => { console.log("视频广告加载成功"); this._isVideoLoaded = true; }); this._rewardVideo.onError((res) => { this._videoFailedCount++; console.warn("视频广告加载失败", res); if (this._videoFailedCount > 10) { console.log("第", this._videoFailedCount, "次重新加载视频广告"); // 失败自动加载广告 this._rewardVideo.load(); } }); this._rewardVideo.onClose((res) => { console.log("视频回调", res); let isEnd = res["isEnded"] as boolean; if (isEnd) { if (this._rewardSuccessed) this._rewardSuccessed(); const resjson = JSON.stringify(res); TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.video_code,{code: resjson}); } else { if (this._rewardSkipped) this._rewardSkipped(); } }); this._rewardVideo.load() } protected _CreateInterstitalAd(){} protected _CreateBannerAd() { if (!this.platformData.bannerId) { console.log("无有效的banner广告ID,取消加载"); return; } let windowWidth = this._base.getSystemInfoSync().windowWidth; let windowHeight = this._base.getSystemInfoSync().windowHeight; let bannerObj = {}; bannerObj["adUnitId"] = this.platformData.bannerId; // "adunit-b48894d44d318e5a"; bannerObj["adIntervals"] = 30; let styleObj = {}; styleObj["left"] = 0; styleObj["top"] = 0; styleObj["width"] = windowWidth; bannerObj["style"] = styleObj; this._bannerAd = this._base.createBannerAd(bannerObj); this._isBannerLoaded = false; if (this._bannerAd) { this._bannerAd.onLoad(() => { console.log("banner加载成功", this._bannerAd); this._isBannerLoaded = true; }); this._bannerAd.onError((res) => { console.warn("banner广告加载失败", res); this._bannerAd == null; }); this._bannerAd.onResize((size) => { this._bannerAd.style.top = windowHeight - size.height; this._bannerAd.style.left = (windowWidth - size.width) / 2; }); } } RecordEvent(eventId: string, param: object) { let reportAnalytics = this._base["reportAnalytics"]; if (reportAnalytics) { if (param == null) { param = {}; } reportAnalytics(eventId, param); } else { console.warn("reportAnalytics 方法不存在"); } } ShowBannerAd() { if (!this.IsBannerAvaliable()) { return; } this._bannerAd.show(); } ShareAppMessage(shareInfo: ShareInfo, onSuccess: Function, onFailed: Function) { console.log("分享消息", shareInfo); let shareObj = this._WrapShareInfo(shareInfo); shareObj["success"] = () => { if (onSuccess) { onSuccess(); } } shareObj["fail"] = () => { if (onFailed) { onFailed(); } } this._base.shareAppMessage(shareObj); } protected _WrapShareInfo(shareInfo: ShareInfo) { let shareObj = {}; if (shareInfo.shareTitle) { shareObj["title"] = shareInfo.shareTitle; } if (shareInfo.shareID) { shareObj["templateId"] = shareInfo.shareID; } if (shareInfo.sharePath) { shareObj["query"] = {}; let pathSplit = shareInfo.sharePath.split("?"); let params = pathSplit[1].split("&"); for (let getParam of params) { let splitParam = getParam.split("="); shareObj["query"][splitParam[0]] = splitParam[1]; } } return shareObj; } OpenGameBox(appIds: string[]) { let openData = []; for (let i = 0; i < appIds.length; ++i) { openData.push({ appId: appIds[i] }); } this._base.showMoreGamesModal({ appLaunchOptions: openData }); } NavigateToApp(appid: string, path?: string, extra?: any): Promise { return new Promise((resolve, reject) => { if (!this.isSupportJumpOther) { reject(false); console.log("当前平台不支持小游戏跳转", this); } else { this._base.showMoreGamesModal({ appLaunchOptions: [ { appId: this.platformData.appId, query: "foo=bar&baz=qux", extraData: {} } ], success(res) { resolve(true); console.log("跳转小游戏成功", appid); }, fail(err) { reject(false); console.log("跳转小游戏失败", appid); } }); } }); } GetUserCloudStorage() { } SetUserCloudStorage() { } _InitABTest(){} createShortcut(BackFun:(isOK:boolean)=>void) { if (sys.os == sys.OS.IOS) { BackFun && BackFun(true) } else if(this.base.addShortcut){ this.base.addShortcut({ success: () => { BackFun && BackFun(true) }, fail: () => { BackFun && BackFun(false) } }) }else{ BackFun && BackFun(true) } } checkShortcut(BackFun:(isOK:boolean)=>void) { if (sys.os == sys.OS.IOS) { // this.base.checkShortcut({ // success: () => { }, // fail: () => { } // }) ConsoleEx.Log("IOS不支持添加桌面图标") BackFun && BackFun(true) } else if(this.base.checkShortcut) { this.base.checkShortcut({ success: (res) => { BackFun && BackFun(res.status.exist) }, fail: () => { BackFun && BackFun(false) } }) }else{ BackFun && BackFun(true) } } requestFeedSubscribe(BackFun:(isOK:boolean)=>void){ this.base.requestFeedSubscribe({ type: "play", allScene: true, success(res) { console.log("requestFeedSubscribe success:", res) BackFun && BackFun(res.success) }, fail(res) { console.log("requestFeedSubscribe fail:", res) BackFun && BackFun(false) }, }) } checkFeedSubscribe(BackFun:(isOK:boolean)=>void) { this.base.checkFeedSubscribeStatus({ type: "play", allScene: true, success(res) { console.log("checkFeedSubscribe success:", res) BackFun && BackFun(res.status) }, fail(res) { console.log("checkFeedSubscribe fail:", res) BackFun && BackFun(false) }, }) } GetFeedType(): number { if (this.lauchOption == null || this.lauchOption.query == null || this.lauchOption.query.feed_game_scene == null || this.lauchOption.query.feed_game_scene == undefined) { return -1; } return Number(this.lauchOption.query.feed_game_scene); } // 登录流程上报 reportScene(sceneID: number) { // 1 启动点击 // 2 资源准备完成 // 3 代码注入完成(加载) // 4 首屏渲染完成 // 7001 游戏可交互 //@ts-ignore const costTime = Date.now() - PlatformManager.instance.PlatformInitTime; console.log('登录流程上报: sceneID = ' + sceneID + ' costTime = ' + costTime) // @ts-ignore tt.reportScene({ sceneId: sceneID, costTime: costTime, dimension: { d1: '1', // value仅支持传入String类型。若value表示Boolean,请将值处理为'0'、'1'进行上报;若value为Number,请转换为String进行上报 }, metric: { m1: '1', // value仅支持传入数值且需要转换为String类型进行上报 }, success(res) { // 上报接口执行完成后的回调,用于检查上报数据是否符合预期 console.log('登录流程上报成功:', res) }, fail(res) { // 上报报错时的回调,用于查看上报错误的原因:如参数类型错误等 console.log('登录流程上报失败:', res) } }) } }