消消方块阵换皮表情
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1162 lines
39 KiB

import { assetManager, game, sys } from "cc";
import { BYTEDANCE, DEBUG, DEV, EDITOR, WECHAT } from "cc/env";
import { RewardedVideoAd } from "./functions/RewardedVideoAd";
import { sdkConfig } from "./sdkConfig";
import GEMgr from "./GEMgr";
import { InterstitialAd } from "./functions/InterstitialAd";
import TTRecording from "./functions/TTRecording";
import { Share } from "./functions/Share";
import Vibrate from "./functions/VibrateMgr";
import { TTRank } from "./functions/TTRank";
import { Singleton } from "../../mx/tools/Singleton";
import { ItemNumType, StatisticsType, StatusType, TaskType } from "../game/GameData";
import { update } from "../../../extensions/tools/source/scene";
import { PfDiagnostics } from "../diagnostics/PfDiagnostics";
import { BattlePerformance } from "../ui/BattleGame/BattlePerformance";
import { MiniGameKind, MiniGamePlatform, MiniGameHostApi } from "./platform/MiniGamePlatform";
import { Physics2DGate } from "../game/Physics2DGate";
/**
* SDK管理器
*/
export class SDKManager extends Singleton {
/**
* 抖音头条录屏相关
*/
private Recording: TTRecording = null;
/**
* 分享相关
*/
Share: Share = new Share();
/**
* 震动
*/
Vibrate = Vibrate;
/**
* 当前平台 API(运行时宿主对象,含各平台扩展能力)
*/
pf: MiniGameHostApi | null = null;
/**
* 平台获取的查询参数
*/
query = "";
showAd = true;
upTestData = false;
levelS: number[] = [];
serverTime: number = 0;
timer: number = 0;
/** 平台 triggerGC 已禁用:主动 GC 会触发卡帧尖刺,改由引擎与内存压力节流应对 */
private _lastPfGcMs = 0;
private static readonly PF_GC_MIN_LEVEL = 15;
private static readonly PF_GC_COOLDOWN_MS = 120000;
/** 是否允许调用平台 triggerGC(线上关闭) */
private static readonly PF_GC_ENABLED = false;
/** 最近一次平台 onMemoryWarning 的 level 与时间(界面打开失败时附带上报) */
private _lastMemWarnLevel: number | null = null;
private _lastMemWarnMs = 0;
/** 激励视频嵌套计数(加载失败重试等场景) */
private _videoAdDepth = 0;
/** 本次广告是否由 SDK 调用了 battle.pause('videoAd') */
private _videoAdBattlePausedBySdk = false;
/**
* 初始化
*/
async init() {
if (EDITOR || DEBUG || sys.isBrowser) {
this.upTestData = true;
return null;
}
MiniGamePlatform.init();
this.pf = MiniGamePlatform.pf;
if (!this.pf) {
return null;
}
if (MiniGamePlatform.kind !== MiniGameKind.Kuaishou) {
this.initUpdate();
}
this.pf.onShow(this.onPfShow.bind(this));
this.pf.onHide(this.onPfHide.bind(this));
this._bindGlobalErrorReporter();
this.serverTime = new Date().getTime();
RewardedVideoAd.init(sdkConfig.config.platformConf.video);
InterstitialAd.init(sdkConfig.config.platformConf.interstitialAd);
this.Share.init(sdkConfig.config.platformConf.shareData);
this.openWXShareMenu()
if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
this.Recording = TTRecording.Ins;
this.Recording.init(sdkConfig.config.platformConf);
}
ZYSDK.ZYSDK.initSdk(sdkConfig.config.pointData.gid)
let serverData = null;
let uid: any = "123456";
while (serverData == null) {
gg.ui.showToast("获取游戏存档...");
uid = await ZYSDK.ZYSDK.getUserId();
console.log("whileUid", uid);
if (uid == null || uid == 1 || uid == "")
await ZYSDK.ZYSDK.initSdk(sdkConfig.config.pointData.gid);
serverData = await this.getServerData();
}
let fun = () => {
let str = serverData;
if (serverData.length > 350) {
str = serverData.substring(0, 350);
}
gg.sdk.reportDY("inLevel", `存档异常-${str}`);
}
if (serverData == "") {
gg.sdk.reportDY("inLevel", `新玩家-${uid}`);
}
else if (serverData == undefined) {
gg.sdk.reportDY("inLevel", `存档异常-undefined`);
}
else {
try {
let sd = JSON.parse(serverData);
if (!Object.hasOwnProperty.call(sd, "uid") || !Object.hasOwnProperty.call(sd, "chapter")) {
fun();
}
} catch (error) {
fun();
}
}
let v = ZYSDK.ZYSDK.getCustomValue();
if (v == 0) this.upTestData = false;
else if (v == 100) this.upTestData = true;
else {
this.upTestData = Math.random() <= v / 100;
}
let lvs = await ZYSDK.ZYSDK.getLevel();
if (lvs && lvs.length > 0) {
this.levelS = lvs;
}
// this.pf.login({
// force: true,
// success(res) {
// console.log(`login 调用成功${res.code} ${res.anonymousCode}`);
// },
// fail(res) {
// console.log(`login 调用失败`);
// },
// });
if (this.timer) {
clearInterval(this.timer);
}
if (sdkConfig.serverTimeCheckInterval > 0) {
await this.updateServerTime();
this.timer = setInterval(() => {
this.updateServerTime();
}, sdkConfig.serverTimeCheckInterval);
}
this.checkTime((curentTime) => {
if (curentTime) {
console.error("时间异常");
this.pfLogKey('SYS:TIME_INVALID', { local: curentTime });
gg.ui.showToast("时间异常,请检查时间设置");
gg.sdk.reportDY("inLevel", `时间异常-本地时间${curentTime}`);
}
});
this.onMemoryWarning((warnRes?: { level?: number }) => {
const level = warnRes?.level;
if (level != null) {
this._lastMemWarnLevel = level;
this._lastMemWarnMs = Date.now();
}
if (level != null && level < 10) return;
// 不主动 triggerGC;改升战斗特效/音效节流档位,减轻内存与卡帧
if (level != null && level >= 10) {
BattlePerformance.onMemoryPressure(level);
}
try {
const info = this.pf.getSystemInfoSync();
const dev = [info.brand, info.model].filter(Boolean).join(' ') || 'unknown';
let detail = level != null ? `lv=${level}|dev=${dev}` : `dev=${dev}`;
if (MiniGamePlatform.isHarmonyOS) {
detail += '|harmony=1';
}
detail += '|gc=0';
if (PfDiagnostics.write('MEM', 'WARN', detail, 600000, 'warn')) {
gg.sdk.reportDY('inLevel', `MEM-warn-${detail}`);
}
} catch { /* ignore */ }
});
return serverData
}
checkTime(callback: Function = null) {
if (!gg.sdk.pf || DEV || DEBUG || sys.isBrowser) {
if (callback) {
callback();
}
return;
}
ZYSDK.ZYSDK.getTimestamp((res) => {
if (res && res.ts) {
let curentTime = new Date().getTime();
let servertime = res.ts * 1000;
console.log("servertime:", servertime);
console.log("curentTime:", curentTime);
if (Math.abs(servertime - curentTime) > 1000 * 60 * 30) {
callback(curentTime);
} else {
if (callback) {
callback();
}
}
}
}, () => {
console.error("获取时间失败");
this.pfLogKey('SYS:TIME_FETCH_FAIL');
});
}
/**获取服务器时间 */
getServerTime() {
// console.log("本机时间毫秒数(UTC):", new Date().getTime());
// console.log("本机时间格式化(UTC):", new Date().toUTCString());
// console.log("本机时间格式化(本地):", new Date().toLocaleString());
// console.log("服务器时间毫秒数:", this.serverTime);
// console.log("服务器时间格式化(UTC):", new Date(this.serverTime).toUTCString());
// console.log("服务器时间格式化(本地):", new Date(this.serverTime).toLocaleString());
if (DEV || DEBUG || sys.isBrowser || sdkConfig.serverTimeCheckInterval == 0) {
let time = new Date().getTime();
//console.log("走了本地时间:", time, "serverTimeCheckInterval:", sdkConfig.serverTimeCheckInterval);
return time;
}
return this.serverTime;
}
/**更新服务器时间 */
updateServerTime() {
return new Promise((resolve, reject) => {
if (!sdkConfig.serverTimeCheckInterval) {
this.serverTime = Date.now();
resolve(null);
return;
}
ZYSDK.ZYSDK.getTimestamp((res) => {
if (res && res.ts) {
let num = res.ts * 1000;
this.serverTime = num;
resolve(null);
}
}, () => {
this.pfLogKey('SYS:SERVER_TIME_FAIL');
resolve(null);
});
});
}
initUpdate() {
const updateManager = this.pf.getUpdateManager();
if (!updateManager) return;
if (updateManager.onUpdateReady) {
updateManager.onUpdateReady((res) => {
this.pf.showModal({
title: "更新提示",
content: "新版本已经准备好,是否重启小游戏?",
success: (res) => {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
// assetManager.cacheManager.clearCache();
updateManager.applyUpdate();
}
},
});
});
}
if (updateManager.onUpdateFailed) {
updateManager.onUpdateFailed((err) => {
// 新的版本下载失败
console.log("版本下载失败原因", err);
this.pfLogKey('SYS:UPDATE_FAIL', err);
this.pf.showToast({
title: "新版本下载失败,请稍后再试",
icon: "none",
});
});
}
if (updateManager.onCheckForUpdate) {
updateManager.onCheckForUpdate();
}
}
restartMiniProgramSync() {
if (this.pf && this.pf.restartMiniProgramSync) {
this.pf.restartMiniProgramSync();
}
}
getServerData() {
if (EDITOR || DEBUG || sys.platform == sys.Platform.DESKTOP_BROWSER || sys.platform == sys.Platform.MOBILE_BROWSER) {
return new Promise<string>((resolve, reject) => {
resolve("");
})
}
return new Promise<string>((resolve, reject) => {
ZYSDK.ZYSDK.getGameData((data) => {
resolve(data);
}, async () => {
resolve(null);
})
})
}
/**
* 当前平台进入前台
* @param res
*/
onPfShow(res) {
console.log("onPfShow", res);
this.query = res.query;
this._show_time = new Date().getTime();
gg.game?.CurentBattle?.TetraMap?.stabilizeAfterViewportChange?.();
//this._restoreVideoAdRuntimeOnForeground();
if (this._onShare) {
let t = new Date().getTime() - this._share_time;
this._onShare(t);
this._onShare = null;
}
// if (res.launch_from == 'homepage' && res.location == 'sidebar_card') {
// //GEvent.Ins.emit(GEventType.CheckIsEnterFromCeBianLan, true);
// gga.data.setStatus(StatusType.DayGiftCanGet, 1);
// gga.data.saveToServer();
// }
if ((res.launch_from == 'homepage' && res.location == 'sidebar_card') || (res.launch_from == 'sidebar_miniprogram' || res.launch_from == 'sidebar_new')) {
//GEvent.Ins.emit(GEventType.CheckIsEnterFromCeBianLan, true);
gg.data.setStatus(StatusType.DayGiftCanGet, 1);
// gg.data.saveToServer();
}
}
private _show_time = 0;
/**
* 当前平台进入后台
*/
onPfHide() {
let c = new Date().getTime();
let t = c - this._show_time;
t = Math.floor(t / 1000);
console.log("onPfHide,在线时长:" + t);
}
/**
* 抖音全屏激励视频:平台会挂起小游戏,禁止再 game.pause()(叠加后易黑屏)。
* 微信 overlay 广告:需 game.pause() 冻结主循环与物理。
*/
private _shouldPauseEngineForVideoAd(): boolean {
return MiniGamePlatform.shouldPauseEngineForVideoAd();
}
/**
* 激励视频播放前:挂起物理/音频/(微信)主循环;战斗由 SDK 统一 pause('videoAd')。
* 调用方不得在 showVideoAd 前自行 battle.pause,否则 leave 无法对称恢复战斗与物理。
*/
private _enterVideoAdPause(): void {
Physics2DGate.suspend(Physics2DGate.VideoAd);
gg.audio.pause();
// if (this._shouldPauseEngineForVideoAd()) {
// }
game.pause();
this._videoAdBattlePausedBySdk = false;
const battle = gg.game?.CurentBattle;
if (battle && !battle.IsGameOver && !battle.IsGamePause) {
battle.pause('videoAd');
this._videoAdBattlePausedBySdk = true;
}
}
private _isVideoAdPaused = false;
/** 激励视频 onClose:与 enter 对称恢复;仅恢复本链路 pause 的战斗。 */
private _leaveVideoAdPause(): void {
// if (this._shouldPauseEngineForVideoAd()) {
// }
game.resume();
Physics2DGate.resume(Physics2DGate.VideoAd);
gg.audio.resume();
if (this._videoAdBattlePausedBySdk) {
gg.game?.CurentBattle?.resumeFromVideoAdSdk();
this._videoAdBattlePausedBySdk = false;
}
}
/**
* 全屏激励视频:从小程序广告页回到游戏画布时,onShow 往往早于 onClose。
* 须先恢复物理/音频/战斗,避免「弹道飞到怪身上却无碰撞」;onClose 仍负责 depth-- 与发奖。
*/
private _restoreVideoAdRuntimeOnForeground(): void {
if (this._videoAdDepth <= 0) return;
if (!RewardedVideoAd.hasPendingCallback()) return;
Physics2DGate.resume(Physics2DGate.VideoAd);
if (this._shouldPauseEngineForVideoAd()) {
game.resume();
}
gg.audio.resume();
if (this._videoAdBattlePausedBySdk) {
gg.game?.CurentBattle?.resumeFromVideoAdSdk();
}
}
/**
* 显示视频广告
* @param callback 回调
*/
showVideoAd(callback: Function) {
console.log('显示视频广告');
if (this._isVideoAdPaused) return;
if (gg.data.getItemNum(ItemNumType.skipAd) > 0) {
gg.data.subItemNum(ItemNumType.skipAd, 1);
callback(true, "skipAd");
return;
}
if (EDITOR || !this.showAd) {
gg.data.addDayTaskProgressData(TaskType.videoAd, 1);
callback(true, "editor");
return;
}
if (sys.isBrowser) {
gg.data.addDayTaskProgressData(TaskType.videoAd, 1);
callback(true, window.location.href);
return;
}
this._isVideoAdPaused = true;
void MiniGamePlatform.checkNetworkForRewardedVideo().then((online) => {
if (!online) {
this._isVideoAdPaused = false;
gg.ui.showToast('网络请求失败,请稍后再试');
this.pfLogKey('AD:NETWORK_OFFLINE');
callback(false);
return;
}
this._enterVideoAdPause();
RewardedVideoAd.show((res) => {
try {
this._isVideoAdPaused = false;
this._leaveVideoAdPause();
if (res) {
callback(true);
gg.data.addStatistics(StatisticsType.TodayAdCount, 1);
gg.data.addDayTaskProgressData(TaskType.videoAd, 1);
ZYSDK.ZYSDK.reportVideo(true);
} else {
this.pfLogKey('AD:REWARD_USER_FAIL');
callback(false);
ZYSDK.ZYSDK.reportVideo(false);
}
} catch (e) {
console.error('[SDKManager] showVideoAd callback error', e);
this.pfLogKey('AD:REWARD_CALLBACK_ERR', e);
}
});
});
}
/**
* 上次显示插屏广告时间戳
*/
private _interAdTimeStamp = 0;
/**
* 显示插屏广告
* @param onAdClose
* @param onFail
*/
showInterstitialAd(onAdClose?: Function, onFail?: Function, useAdLevel = false) {
if (EDITOR) {
onAdClose && onAdClose(true, "editor");
} else if (sys.isBrowser) {
onAdClose && onAdClose(true, window.location.href);
} else {
if (!useAdLevel || ZYSDK.ZYSDK.getAdLevel() == 1) {
//判断是否间隔x秒
let curTime = new Date().getTime();
if (curTime - this._interAdTimeStamp < ZYSDK.ZYSDK.getAdInterval() * 1000) {
onFail && onFail();
return;
}
this._interAdTimeStamp = curTime;
InterstitialAd.showInterstitialAd(onAdClose, onFail, () => {
this.reportDY("inLevel", `插屏-章节${gg.data.doc.chapter}`);
});
}
}
}
/**
* 设置排行榜
* @param value 分数
* @param dataType 数据类型 0 数字类型 1 字符串类型
* @param priority 权重
* @param zoneId 排行榜分区
*/
setImRankData(value: number | string, dataType = 0, priority = 0, zoneId = "default") {
if (EDITOR) {
console.log('平台无法写入排行榜数据')
} else if (sys.isBrowser) {
console.log('平台无法写入排行榜数据')
} else {
TTRank.setImRankData(value, dataType, priority, zoneId)
}
}
/**
* 获取排行榜
* @param rankTitle 排行榜标题
* @param suffix 分数后缀补充文案 为空或不填,一般枚举类型不需要填后缀
* @param rankType 排行榜类型 可选值有:day、week、month、month、all
* @param zoneId 排行榜分区
* @param dataType 数据类型: 0 数字类型 1 字符串类型
* @param relationType 排行榜类型 可选值有:default 好友榜、总榜都展示 friend 仅展示好友榜 all 仅展示总榜
*/
getImRankList(rankTitle: string = "排行榜", suffix = "", rankType = "all", zoneId = "default", dataType = 0, relationType = "default") {
if (EDITOR) {
console.log('平台无法获取排行榜数据')
} else if (sys.isBrowser) {
console.log('平台无法获取排行榜数据')
} else {
TTRank.getImRankList(rankTitle, suffix, rankType, zoneId, dataType, relationType)
}
}
/**
* 打点
* @param event
* @param msg
*/
reportDY(event, msg) {
//添加打点打印和格式,带颜色
//console.log("%c打点==", "color:green", msg);
if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
// window["tt"].reportAnalytics(event, {
// type: msg,
// });
ZYSDK.ZYSDK.reportUserAction(msg);
GEMgr.GEReportEvent(msg);
}
if (sys.platform == sys.Platform.WECHAT_GAME) {
//event = event.toLowerCase();
// window["wx"].reportEvent(event, {
// "type": msg,
// });
ZYSDK.ZYSDK.reportUserAction(msg);
GEMgr.GEReportEvent(msg);
}
}
/**
* 进入抖音侧边栏
* @param callback
*/
enterSidebar(callback?: Function) {
if (window["tt"] && window["tt"].navigateToScene) {
window["tt"].navigateToScene({
scene: "sidebar",
success: (res) => {
console.log("navigate to scene success");
if (callback) callback(true);
},
fail: (res) => {
console.log("navigate to scene fail: ", res);
if (callback) callback(false);
},
})
} else if (window["ks"] && window["ks"].navigateToScene) {
window["ks"].navigateToScene({
scene: "sidebar",
success: (res) => {
console.log("navigate to scene success");
if (callback) callback(true);
},
fail: (res) => {
console.log("navigate to scene fail: ", res);
if (callback) callback(false);
},
})
} else {
if (callback) callback(true);
}
}
/**验证是否支持侧边栏 */
checkSidebar(callback?: Function) {
if (window["tt"] && window["tt"].navigateToScene) {
if (callback) callback(true);
} else if (window["ks"]) {
if (window["ks"].checkSliderBarIsAvailable) {
window["ks"].checkSliderBarIsAvailable({
success: (result) => {
console.log("check slider bar is available success: ", result.available);
if (result && result.available) {
if (callback) callback(true);
} else {
if (callback) callback(false);
}
},
fail: (res) => {
console.log("check slider bar is available fail: ", res);
if (callback) callback(false);
},
})
} else {
if (callback) callback(false);
}
} else {
if (callback) callback(false);
}
// if (!window["tt"]) {
// if (callback) callback(false);
// return;
// } else {
// window["tt"].checkScene({
// scene: "sidebar",
// success: (res) => {
// console.log("check scene success: ", res.isExist);
// //成功回调逻辑
// if (callback) callback(true);
// },
// fail: (res) => {
// console.log("check scene fail:", res);
// //失败回调逻辑
// if (callback) callback(false);
// }
// });
// }
}
/**
* 验证是否需要显示添加到桌面按钮
* @param callback
*/
checkNeedShowAddShortcut(callback?: Function) {
if (!window["tt"]) callback?.(false);
else if (!window["tt"].addShortcut) callback?.(false);
else callback?.(true);
}
/**
* 分享游戏
* @param timeLimit 分享最小停留时间, 没有回调的平台通过计时判断是否分享成功
* @param cb 有回调的平台,通过回调函数判断是否分享成功
* @param data 可选参数,分享数据(需要知道参数类型)
*/
share(timeLimit, cb = null, data = null) {
this._share_time = new Date().getTime();
if (this.Share) {
let desc = ""
let url = ""
let query = ""
let id = "";
if (data && data.desc) desc = data.desc;
if (data && data.res) url = data.res;
if (data && data.query) query = data.query;
if (data && data.shareid) id = data.shareid;
if (sys.platform == sys.Platform.WECHAT_GAME
|| MiniGamePlatform.kind === MiniGameKind.Kuaishou
|| MiniGamePlatform.kind === MiniGameKind.Bilibili) {
this._onShare = (time) => {
console.log("本次分享时间:" + time);
if (time >= timeLimit) {
if (cb) cb(true);
}
else {
if (cb) cb(false);
}
}
this.Share.share(desc, url, cb, query);
} else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
this.Share.share(desc, url, cb, query, id);
} else {
cb(true);
}
}
else {
cb(true);
}
}
private _share_time = 0;
private _onShare = null;
/**
* 短时间震动
*/
vibrateShort() {
this.Vibrate.vibrateShort();
}
/**
* 长时间震动
*/
vibrateLong() {
this.Vibrate.vibrateLong();
}
/**
* 开始震动
*/
startVibrate() {
this.Vibrate.startVibrate();
}
/**
* 停止震动
*/
stopVibrate() {
this.Vibrate.stopVibrate();
}
/**
* 添加到桌面
* @param callback 回调
*/
addShortcut(callback?: Function) {
if (window["tt"] && window["tt"].addShortcut) {
window["tt"].addShortcut({
success: function (res) {
console.log("添加成功");
if (callback) callback(true);
},
fail: function (res) {
console.log("添加失败", res);
if (callback) callback(false);
}
})
} else if (window["ks"] && window["ks"].addShortcut) {
window["ks"].addShortcut({
success: function (res) {
console.log("添加成功");
if (callback) callback(true);
},
fail: function (res) {
console.log("添加失败");
if (callback) callback(false);
}
})
} else {
if (callback) callback(false);
}
}
getVideoPath() {
return this.Recording?.getVideoPath();
}
getVideoTime() {
return this.Recording?.getVideoTime();
}
getStatus() {
return this.Recording?.getStatus();
}
/**
* 开始录屏
*/
startRecord() {
this.Recording && this.Recording.startVideo();
}
/**
* 停止录屏
*/
stopRecord() {
this.Recording && this.Recording.stopVideo();
}
/**
* 分享录屏
*/
shareRecord(callback = null) {
if (this.Recording)
this.Recording.shareVideo(callback);
else
callback(true);
}
pauseVideo() {
this.Recording && this.Recording.pauseVideo();
}
resumeVideo() {
this.Recording && this.Recording.resumeVideo();
}
/**
* 微信转发菜单
*/
openWXShareMenu() {
if (WECHAT) {
window["wx"].showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline'],
success: () => {
},
fail: () => {
},
complete: () => {
}
});
window["wx"].onShareAppMessage(function () {
let share1 = {
title: sdkConfig.config.platformConf.wxOnShareMessage.title,
imageUrlId: sdkConfig.config.platformConf.wxOnShareMessage.imageUrlId,
imageUrl: sdkConfig.config.platformConf.wxOnShareMessage.imageUrl
}
// let share2 = {
// title: "看不见下雨了嘛,赶紧回笼呀!",
// imageUrlId: 'Y2PHkx0bR0Ou2a25kg+Vsg==',
// imageUrl: 'https://mmocgame.qpic.cn/wechatgame/WFTmogtfYrIwyhRVuZHbEs709mroiaaDcYkwBSBXLckR7ibQNPfrXKstvCpyV4bmyn/0'
// }
// let share3 = {
// title: "快救救这只猪",
// imageUrlId: 'qTQmv6/8SCixA6raayq2HA==',
// imageUrl: 'https://mmocgame.qpic.cn/wechatgame/qqRAxsORaczSj5Z33DB4pneEtpOBstVwzhsk8VPh02OlTGHzPHBxicaffB09ILdgl/0'
// }
// return Math.random() > 0.5 ? share1 : Math.random() > 0.5 ? share2 : share3;
return share1
});
if (gg.data.getStatistics(StatisticsType.yonghuxieyiYS) == 0) {
window["wx"].getPrivacySetting({
success: (res) => {
console.log("是否需要授权:", res.needAuthorization);
console.log("隐私协议名称:", res.privacyContractName);
if (res.needAuthorization) {
window["wx"].requirePrivacyAuthorize({
success: () => {
// 用户同意授权
// runGame() 继续游戏逻辑
console.log("用户同意授权");
gg.data.setStatistics(StatisticsType.yonghuxieyiYS, 2);
},
fail: () => {
console.log("用户拒绝授权");
gg.data.setStatistics(StatisticsType.yonghuxieyiYS, 1);
}, // 用户拒绝授权
complete: () => { }
})
} else {
}
},
fail: () => {
// 低版本基础库不支持时的处理
}
});
}
}
}
getUserInfo() {
return new Promise((resolve, reject) => {
if (this._userInfo) {
resolve(this._userInfo);
return;
}
if (!this.pf || !this.pf["getUserInfo"]) {
resolve(null);
return;
}
this.pf["getUserInfo"]({
// withCredentials: true,
// withRealNameAuthenticationInfo: true,
success(res) {
console.log(`getUserInfo 调用成功`, res.userInfo, res.encryptedData, res.iv, res.signature);
this._userInfo = res.userInfo;
resolve(res.userInfo);
},
fail(res) {
console.log(`getUserInfo 调用失败`, res.errMsg);
resolve(null);
},
});
});
}
private _userInfo: any = null;
//推荐流订阅
PlatformFeedSubscribe() {
console.log('PlatformFeedSubscribe')
let self = this
if (this.pf && window["tt"]) {
console.log('PlatformFeedSubscribe1')
let sceneId = 1 //离线收益场景
let self = this
if (this.pf.canIUse("checkFeedSubscribeStatus")) {
console.log('PlatformFeedSubscribe2')
this.pf.checkFeedSubscribeStatus({
type: "play",
scene: 1,
success(res) {
console.log("checkFeedSubscribeStatus:" + res.status)
if (!res.status) {
// 用户没订阅
let contentIDs = sdkConfig.config.platformConf.contentIDs || [];
console.log("contentIDs:", contentIDs)
self.pf.requestFeedSubscribe({
type: "play",
scene: sceneId,
contentIDs: contentIDs,
success(res) {
console.log("requestFeedSubscribe:" + res.success)
},
fail(res) {
console.log(res.errMsg)
},
})
}
},
fail(res) {
console.log(res.errMsg)
},
})
}
}
}
//推荐流上报场景
PlatformReportScene() {
if (this.pf && this.pf.reportScene) {
this.pf.reportScene({
sceneId: 7001,
costTime: 2000,
success(res) {
// 上报接口执行完成后的回调,用于检查上报数据是否符合预期
console.log("ReportScene_success:" + res)
},
fail(res) {
// 上报报错时的回调,用于查看上报错误的原因:如参数类型错误等
console.log("ReportScene_fail:" + res)
}
})
}
}
getLaunchOptionsSync_custom() {
if (this.pf && this.pf.getLaunchOptionsSync) {
let obj = this.pf.getLaunchOptionsSync();
let str = JSON.stringify(obj);
console.log("getLaunchOptionsSync_custom: 场景值", str)
///obj.scene
return obj
} else {
return null
}
}
private _bindGlobalErrorReporter(): void {
try {
const pf = this.pf as MiniGameHostApi & {
onError?: (cb: (err: unknown) => void) => void;
onUnhandledRejection?: (cb: (res: { reason?: unknown }) => void) => void;
};
pf?.onError?.((err) => {
this.pfLogKey('RUNTIME:UNCAUGHT', err, 300000);
});
pf?.onUnhandledRejection?.((res) => {
this.pfLogKey('RUNTIME:PROMISE_REJECT', res?.reason, 300000);
});
} catch { /* ignore */ }
}
/** 同 tag 平台日志冷却(毫秒),避免刷爆配额 */
private _pfLogKeyLastMs: Record<string, number> = {};
/**平台记录日志 */
pfLog(msg: string) {
if (this.pf && this.pf.getLogManager) {
this.pf.getLogManager().log(msg);
} else {
console.log(msg);
}
}
/**
* 关键行为 / 失败 / 异常 → 平台日志(getLogManager + RealtimeLogManager)。
* @param tag 短标签,如 RES:PREFAB_FAIL、AD:REWARD_SHOW_FAIL
* @param detail 附加信息(字符串、Error 或可 JSON 序列化对象)
* @param cooldownMs 同 tag 冷却,默认 60s
*/
pfLogKey(tag: string, detail?: unknown, cooldownMs = 60000): void {
if (!tag) return;
const now = Date.now();
const last = this._pfLogKeyLastMs[tag] ?? 0;
if (now - last < cooldownMs) return;
this._pfLogKeyLastMs[tag] = now;
const ctx = this._formatPfLogContext();
const detailStr = this._stringifyPfDetail(detail);
let msg = detailStr ? `[${tag}] ${ctx} ${detailStr}` : `[${tag}] ${ctx}`;
if (msg.length > 250) msg = msg.slice(0, 250);
this.pfLog(msg);
try {
const pfAny = this.pf as { getRealtimeLogManager?: (opts?: { syncToConsole?: boolean }) => { error?: (m: string) => void } } | null;
const getRt = pfAny?.getRealtimeLogManager;
if (typeof getRt === 'function') {
getRt.call(pfAny, { syncToConsole: !!DEV })?.error?.(msg);
}
} catch { /* ignore */ }
if (DEV) {
console.warn('[pfLogKey]', msg);
}
}
private _formatPfLogContext(): string {
const b = gg.game?.CurentBattle;
const ch = b?.getReportDYChapterId?.() ?? gg.data?.doc?.chapter ?? 0;
const wave = b?.CurentWaveNum ?? 0;
return `ch${ch}_w${wave}`;
}
private _stringifyPfDetail(detail: unknown): string {
if (detail == null) return '';
if (typeof detail === 'string') return detail;
if (detail instanceof Error) return `${detail.name}:${detail.message}`;
try {
const s = JSON.stringify(detail);
return s.length > 140 ? s.slice(0, 140) : s;
} catch {
return String(detail);
}
}
/**平台记录调试日志 */
pfDebug(msg: string) {
if (this.pf && this.pf.getLogManager) {
this.pf.getLogManager().debug(msg);
} else {
console.debug(msg);
}
}
ttWorker(callback) {
// if (this.pf && this.pf.createWorker) {
// let worker = this.pf.createWorker({
// scriptPath: "worker.js",
// success: (res) => {
// console.log("createWorker success", res);
// callback(res);
// },
// fail: (res) => {
// console.log("createWorker fail", res);
// },
// });
// }
}
/** 界面打开失败等场景:附带最近一次内存告警等级与距今秒数 */
getMemWarnState(): { level: number | null; agoSec: number | null } {
if (this._lastMemWarnLevel == null) {
return { level: null, agoSec: null };
}
return {
level: this._lastMemWarnLevel,
agoSec: Math.floor((Date.now() - this._lastMemWarnMs) / 1000),
};
}
formatMemWarnForPf(): string {
const s = this.getMemWarnState();
if (s.level == null) {
return 'memLv=na';
}
return `memLv=${s.level}|memAgo=${s.agoSec}s`;
}
formatMemWarnForDy(): string {
const s = this.getMemWarnState();
if (s.level == null) {
return 'memna';
}
return `mem${s.level}_ago${s.agoSec}s`;
}
/**
* 平台 triggerGC(已禁用)。
* 线上数据 8/21 卡顿率 11%→14% 与进/离局 force GC 高度相关;改由 releaseBundle + 内存压力节流。
*/
pfTriggerGC(_force = false): boolean {
if (!SDKManager.PF_GC_ENABLED) {
return false;
}
if (!this.pf?.triggerGC) {
return false;
}
const now = Date.now();
if (!_force && now - this._lastPfGcMs < SDKManager.PF_GC_COOLDOWN_MS) {
return false;
}
this._lastPfGcMs = now;
try {
this.pf.triggerGC();
return true;
} catch {
return false;
}
}
/** 平台内存警告(callback 参数含 level,Android/鸿蒙等) */
onMemoryWarning(callback: ((res?: { level?: number }) => void) | null = null) {
if (this.pf && this.pf.onMemoryWarning) {
this.pf.onMemoryWarning((res?: { level?: number }) => {
callback?.(res);
});
}
}
}