Files
MatchMaster/assets/Script/GameManager.ts
T
2026-10-16 16:24:28 +08:00

1227 lines
54 KiB
TypeScript

// Learn TypeScript:
// - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
// - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
// - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
import Utils from "./module/Pay/Utils";
import BattlePassSettlementCheck from './module/Config/BattlePassSettlementCheck';
import CloudRiseService from "./module/Config/CloudRiseService";
import ActivityScheduleService from "./module/Config/ActivityScheduleService";
import PyramidService from "./module/Config/PyramidService";
import GoldMinerService from './coin_madness/GoldMinerService';
import { MiniGameManager } from "./Sdk/MiniGameManager";
import { MiniGameSdk } from "./Sdk/MiniGameSdk";
import MiniProgramBenefitsBridge from "./module/MiniProgramBenefitsBridge";
import WucaiEntry from "./module/WucaiEntry";
import ClientUpdate from "./module/Config/ClientUpdate";
import DailyTaskProgressTracker from "./module/Task/DailyTaskProgressTracker";
import ServerEnvironment from "./module/Config/ServerEnvironment";
import ServerSwitch from "./module/Config/ServerSwitch";
import ThreeWinStreak from "./ThreeWinStreak";
const { ccclass, property } = cc._decorator;
@ccclass
export default class GameManager extends cc.Component {
@property(cc.Label)
label: cc.Label = null;
@property(cc.Sprite)
progress: cc.Sprite = null;
@property(cc.Node)
lizi: cc.Node = null;
@property
text: string = 'hello';
static _instance: GameManager = null;
@property(cc.Prefab)
staminaPackPrefab: cc.Prefab = null;
@property({ type: [cc.Prefab], tooltip: "方块数组" })
Block_Array: Array<cc.Prefab> = [];
@property({ type: [cc.Prefab], tooltip: "墙壁数组" })
Wall_Prefab: Array<cc.Prefab> = [];
particleEffects: cc.ParticleAsset[];
// @property({type: [cc.ParticleSystem], tooltip:"粒子数组"})
// particleEffects : Array<cc.ParticleSystem> = [];
load1: boolean = false;
load2: boolean = false;
load3: boolean = false;
load4: boolean = false;
load5: boolean = false;
load6: boolean = false;
register_time: number = 0;
scheduleCallback: any;
timeNumber: number;
nowTime: number;
shouldClearForcedUpdate: boolean = false;
private wucaiTransferShown: boolean = false;
private shushuLoggedIn: boolean = false;
private autoWucaiLevelAmount: any = null;
private onTaskNetworkStatus = (status: { isConnected: boolean }) => {
cc.fx.GameTool.onDailyTaskNetworkChange(status.isConnected);
};
// LIFE-CYCLE CALLBACKS:
/** 游戏入口初始化 */
onLoad() {
ServerEnvironment.current();
DailyTaskProgressTracker.startOnline();
window.initMgr();
this.register_time = 0;
this.timeNumber = 2;
// cc.director.preloadScene("HomeScene", (err, asset) => {
// });
this.startTimeCutDown();
cc.fx.GameConfig.init(true);
ThreeWinStreak.restore();
ClientUpdate.initialize();
cc.fx.GameConfig.GM_INFO.sceneValue = "loadScene";
cc.fx.GameConfig.GM_INFO.gameState = false;
//@ts-ignore
if (typeof wx !== 'undefined' && wx !== null) {
//@ts-ignore
const launchOptions = wx.getLaunchOptionsSync();
MiniProgramBenefitsBridge.instance.capture(launchOptions, "cold");
this.updateWucaiEntry(launchOptions, true);
const query = launchOptions.query || {};
if (query.ge_ad_id) cc.fx.GameConfig.GM_INFO.ge_ad_id = query.ge_ad_id;
if (query.ge_creative_id) cc.fx.GameConfig.GM_INFO.ge_creative_id = query.ge_creative_id;
// 遍历 query 中除已知参数之外的其他参数
for (const key in query) {
if (key !== 'ge_ad_id' && key !== 'ge_creative_id' && key !== 'from'
&& key !== 'wucai_entry_id' && key !== 'wucai_resume') {
cc.fx.GameTool.trackErrorToShushu({ message: key });
}
}
}
//cc.fx.GameTool.trackErrorToShushu({ message: "ge_ad_id" });
setTimeout(() => {
cc.fx.GameTool.initWechatErrorTracking();
}, 500);
this.readMusicConfig();
this.load1 = this.load2 = this.load3 = this.load4 = this.load5 = this.load6 = false;
setTimeout(() => {
this.getSetting();
this.readUserData();
this.getShareInfo();
}, 100);
if (GameManager._instance == null) {
GameManager._instance = this;
cc.game.addPersistRootNode(this.node);
}
else {
return;
}
// 检测微信小游戏切到后台
if (cc.sys.platform === cc.sys.WECHAT_GAME || cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
//@ts-ignore
wx.onHide(() => {
this.onHide();
});
// 检测微信小游戏回到前台
//@ts-ignore
wx.onShow((options) => {
this.onShow(options);
});
//@ts-ignore
if (wx.onNetworkStatusChange) wx.onNetworkStatusChange(this.onTaskNetworkStatus);
}
cc.tween(this.progress)
.to(1.8, { fillRange: 0.7 })
.start();
cc.tween(this.lizi)
.to(1.8, { position: cc.v3(-400 + 810 * 0.7, -520, 0) })
.start();
}
start() {
setTimeout(() => {
const path = 'prefab/block';
const path2 = 'prefab/wall';
cc.resources.loadDir(path, cc.Prefab, (err, assets: cc.Prefab[]) => {
if (err) {
cc.director.loadScene("LoadScene");
return;
}
// 将加载的 Prefab 赋值给 Block_Array
this.Block_Array = assets;
this.setSort();
this.load1 = true;
});
cc.resources.loadDir(path2, cc.Prefab, (err, assets: cc.Prefab[]) => {
if (err) {
cc.director.loadScene("LoadScene");
return;
}
// 将加载的 Prefab 赋值给 Block_Array
this.Wall_Prefab = assets;
this.load2 = true;
this.setWallPrefabSort();
});
}, 100);
}
onDestroy() {
//@ts-ignore
if (typeof wx !== "undefined" && wx.offNetworkStatusChange) wx.offNetworkStatusChange(this.onTaskNetworkStatus);
}
onHide() {
WucaiEntry.onHide();
DailyTaskProgressTracker.stopOnline();
cc.fx.GameTool.onDailyTasksBackground();
// 只暂停游戏逻辑,不要 stopMusic —— 微信小游戏 InnerAudioContext 的 resumeMusic 经常失效
// 用 pauseAll,回前台时用 resumeAll 续播,保证退回 HomeScene 时音乐不被中断/丢失
cc.audioEngine.pauseAll();
cc.game.pause();
}
onShow(options?: any) {
if (ClientUpdate.onShow()) return;
if (ServerSwitch.inProgress) return;
DailyTaskProgressTracker.startOnline();
cc.fx.GameTool.onDailyTasksForeground();
if (options) {
this.updateWucaiEntry(options);
MiniProgramBenefitsBridge.instance.capture(options, "show");
}
cc.audioEngine.resumeAll();
cc.game.resume();
if (WucaiEntry.pendingEntryId && cc.director.getScene()?.name === "HomeScene") {
const home: any = cc.find("Canvas")?.getComponent("JiaZai");
if (home) home.resumeWucaiEntry();
}
}
private updateWucaiEntry(options: any, cold = false): void {
if (cold) WucaiEntry.captureLaunch(options);
else WucaiEntry.captureShow(options);
cc.fx.GameConfig.GM_INFO.isFromWucai = !!(WucaiEntry.loginEntryId || WucaiEntry.pendingEntryId);
}
//#region 给加载好的墙壁资源排序
/** 给加载好的墙壁资源排序,防止乱序 */
setWallPrefabSort() {
const order = ['down', 'downleft', 'downright', 'left', 'leftdown', 'leftup', 'right', 'rightdown', 'rightup', 'up', 'upleft', 'upright'];
this.Wall_Prefab.sort((a, b) => {
const indexA = order.indexOf(a.name);
const indexB = order.indexOf(b.name);
if (indexA === -1) return 1;
if (indexB === -1) return -1;
return indexA - indexB;
});
}
/** 给加载好的方块资源排序,防止乱序 */
setSort() {
this.Block_Array.sort((a, b) => {
// 从名称中提取数字部分
const numberA = parseInt(a.name.match(/\d+/)?.[0] || '0', 10);
const numberB = parseInt(b.name.match(/\d+/)?.[0] || '0', 10);
return numberA - numberB;
});
}
//#region 开始游戏
/** 开始游戏,执行逻辑 */
startGame() {
// Fetch the entry state while the loading screen and shop bundle are still loading.
const activity = GoldMinerService.current();
const activityReady = activity ? activity.readForDisplay().catch(error => {
cc.warn('首页活动状态读取失败', error.message);
}) : Promise.resolve();
cc.tween(this.progress)
.to(0.5, { fillRange: 1 })
.start();
cc.tween(this.lizi)
.to(0.5, { position: cc.v3(410, -516.426, 0) })
.start();
cc.assetManager.loadBundle('publicUI', (publicUIError) => {
if (publicUIError) {
console.error('加载 publicUI 失败:', publicUIError);
return;
}
activityReady.then(() => { if (!ClientUpdate.blocked && cc.isValid(this.node)) cc.director.loadScene("HomeScene"); });
});
}
//#region 微信登录,以及读取用户信息
/** 微信登录,以及读取用户信息 */
private setABTests(abTests) {
cc.fx.GameConfig.GM_INFO.abTestAssignments = {};
cc.fx.GameConfig.GM_INFO.abTests = {
layer_one: 0,
layer_two: 0,
layer_three: 0
};
if (!abTests) {
return;
}
if (typeof abTests === "string") {
try {
abTests = JSON.parse(abTests);
} catch (e) {
return;
}
}
if (Object.keys(abTests).length === 0) {
return;
}
cc.fx.GameConfig.GM_INFO.abTestAssignments = abTests;
const layerMap = {
"layer_1": "layer_one",
"layer_2": "layer_two",
"layer_3": "layer_three"
};
const groupMap = {
"1": 1,
"2": 2,
"A": 1,
"B": 2,
"C": 3,
"D": 4,
"E": 5
};
for (const key in abTests) {
const item = abTests[key];
if (!item) {
continue;
}
const layerKey = layerMap[key] || layerMap["layer_" + item.layer];
const groupKey = String(item.group || "").toUpperCase();
const groupValue = groupMap[groupKey] || 0;
if (layerKey && groupValue > 0) {
cc.fx.GameConfig.GM_INFO.abTests[layerKey] = groupValue;
}
}
// console.log("_________________________abTests:", cc.fx.GameConfig.GM_INFO.abTests);
}
readUserData(retryCount = 0) {
if (ClientUpdate.blocked) return;
const wucaiEntryId = WucaiEntry.loginEntryId;
//@ts-ignore
if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) {
MiniGameSdk.API.tencent_Init();
MiniGameSdk.API.shushu_Init();
this.nowTime = Date.now();
// 最大重试次数
const MAX_RETRIES = 30;
// 延迟时间数组,按照 1 秒 3 次、2 秒 5 次、5 秒 6 次、15 秒 5 次的规则生成
const delays = [
...Array(3).fill(3000),
...Array(5).fill(4000),
...Array(6).fill(5000),
...Array(5).fill(15000)
];
const attemptUserInfo = () => {
if (ClientUpdate.blocked) return;
Utils.getUserInfo((data) => {
if (ClientUpdate.blocked) return;
if (data.code == 1) { // 假设返回数据中有 success 字段表示成功
// console.log("登錄", data);
let systemInfo = null;
if (cc.sys.platform === cc.sys.WECHAT_GAME)
//@ts-ignore
systemInfo = wx.getSystemInfoSync();
else if (cc.sys.platform === cc.sys.BYTEDANCE_GAME)
//@ts-ignore
systemInfo = tt.getSystemInfoSync();
if (data.data.openid) {
cc.fx.GameConfig.GM_INFO.openid = data.data.openid;
cc.fx.StorageMessage.setStorage("openid", cc.fx.GameConfig.GM_INFO.openid);
MiniGameSdk.API.tencent_SetOpenId(cc.fx.GameConfig.GM_INFO.openid);
}
// console.log("系统信息________:", data.data.version);
if (data.data.version) {
let result = cc.fx.GameTool.compareVersion(cc.fx.GameConfig.GM_INFO.version, data.data.version);
// console.log("版本号:", result);
if (result == 1 && systemInfo.platform == 'ios') {
// console.log("ios版本号");
cc.fx.GameConfig.GM_INFO.canIos = false;
}
else
cc.fx.GameConfig.GM_INFO.canIos = true;
}
if (data.data.token) {
cc.fx.GameConfig.GM_INFO.token = data.data.token;
}
BattlePassSettlementCheck.resetLogin();
const wucaiType = Number(data.data.wucai_type);
cc.fx.GameConfig.GM_INFO.wucai_type = Number.isInteger(wucaiType) ? wucaiType : -1;
cc.fx.GameConfig.GM_INFO.wucai_entry_id = data.data.wucai_entry_id || "";
cc.fx.GameConfig.GM_INFO.wucai_reward_granted = data.data.wucai_reward_granted === true;
WucaiEntry.loginEntryId = "";
cc.fx.GameConfig.GM_INFO.wucai_preview = data.data.wucai_preview || null;
this.autoWucaiLevelAmount = cc.fx.GameConfig.GM_INFO.wucai_type === 0
&& data.data.forcedUpdate === true
? data.data.levelAmount
: null;
cc.fx.GameConfig.GM_INFO.wucai_current_preview =
cc.fx.GameConfig.GM_INFO.wucai_type === 1
? this.buildWucaiCurrentPreview(data.data)
: null;
cc.fx.GameConfig.GM_INFO.wucai_reward_popup_pending =
data.data.wucai_reward_popup_pending === true;
this.shouldClearForcedUpdate = data.data.forcedUpdate === true;
this.setJungleTreasureLoginState(data.data);
// 抽猫红点直接使用登录返回的数据,不额外请求接口。
const loginFilm = data.data.film !== undefined
&& data.data.film !== null
&& data.data.film !== ""
? data.data.film
: data.data.levelAmount;
cc.fx.GameConfig.GM_INFO.film = Number(loginFilm) || 0;
cc.fx.GameConfig.GM_INFO.catArr = Array.isArray(data.data.catArr)
? data.data.catArr.slice()
: [1, 2, 3];
if (data.data.abTests)
this.setABTests(data.data.abTests);
if (data.data.forcedUpdate) {
const timestamp = Date.now();
cc.fx.GameConfig.GM_INFO.level = data.data.levelAmount;
let levelInfo = { "level": cc.fx.GameConfig.GM_INFO.level, "timestamp": timestamp };
cc.fx.StorageMessage.setStorage("level", levelInfo);
}
if (data.data._id) {
cc.fx.GameConfig.GM_INFO.uid = data.data._id;
cc.fx.StorageMessage.setStorage("uid", data.data._id);
// console.log("_________________用户UID", cc.fx.GameConfig.GM_INFO.uid);
}
if (data.data.onlyId) {
cc.fx.GameConfig.GM_INFO.userId = data.data.onlyId;
}
if (data.data.outTradeNo) {
if (data.data.outTradeNo.length > 0) {
cc.fx.GameConfig.GM_INFO.allOutTradeNo = [];
cc.fx.GameConfig.GM_INFO.allOutTradeNo = data.data.outTradeNo;
}
}
if (data.data.shareLv) {
if (data.data.shareLv.length > 0) {
cc.fx.GameConfig.GM_INFO.helpLevel = data.data.shareLv[0].lv;
}
}
if (data.data.username) {
cc.fx.GameConfig.GM_INFO.username = data.data.username;
}
if (data.data.useravatar) {
cc.fx.GameConfig.GM_INFO.useravatarIcon = data.data.useravatar;
if (cc.fx.GameConfig.GM_INFO.useravatarIcon == "4")
cc.fx.GameConfig.GM_INFO.useravatarIcon = "5";
else if (cc.fx.GameConfig.GM_INFO.useravatarIcon == "10" || cc.fx.GameConfig.GM_INFO.useravatarIcon == "14")
cc.fx.GameConfig.GM_INFO.useravatarIcon = "7";
if (cc.fx.GameConfig.GM_INFO.useravatarIcon) {
if (cc.fx.GameConfig.GM_INFO.useravatarIcon.length < 10)
cc.fx.GameConfig.GM_INFO.useravatarIcon = "icon_" + cc.fx.GameConfig.GM_INFO.useravatarIcon
}
}
if (data.data.useravatarIcon) {
cc.fx.GameConfig.GM_INFO.useravaterkuang = data.data.useravatarIcon;
cc.fx.GameConfig.GM_INFO.useravaterkuang = "kuang_" + (parseInt(cc.fx.GameConfig.GM_INFO.useravaterkuang) + 1);
}
if (data.data.userCat) {
cc.fx.GameConfig.GM_INFO.useravatarCat = data.data.userCat;
cc.fx.GameConfig.GM_INFO.useravatarCat = "cat_" + cc.fx.GameConfig.GM_INFO.useravatarCat;
// console.log("我的猫:", cc.fx.GameConfig.GM_INFO.useravatarCat);
}
if (data.data.register_time) {
this.register_time = data.data.register_time;
// console.log("注册时间:", data.data.register_time);
cc.fx.GameConfig.GM_INFO.firstTime = data.data.register_time;
} else {
let time = Date.now();
this.register_time = time;
}
if (data.data.task) {
let task = JSON.parse(data.data.task);
cc.fx.GameConfig.GM_INFO.tasks = task;
}
cc.fx.GameConfig.GM_INFO.hourglassAmount = Number(data.data.hourglassAmount) || 0;
cc.fx.GameConfig.GM_INFO.rocketAmount = Number(data.data.rocketAmount) || 0;
cc.fx.GameConfig.GM_INFO.infiniteHourglassTime = Number(data.data.infiniteHourglassTime) || 0;
cc.fx.GameConfig.GM_INFO.infiniteRocketTime = Number(data.data.infiniteRocketTime) || 0;
if (data.data.addLevel) {
cc.fx.GameConfig.GM_INFO.addLevel = data.data.addLevel;
}
if (data.data.address) {
cc.fx.GameConfig.GM_INFO.address = data.data.address;
}
// console.log("服务器强制刷新状态__________", data.data.forcedUpdate);
//如果有连胜记录,就赋值
ThreeWinStreak.restore(data.data, data.data.forcedUpdate === true);
if (cc.fx.GameConfig.forceOldRainbowWinStreakC || cc.fx.GameConfig.forceRainbowWinStreakB) {
cc.fx.GameConfig.GM_INFO.winStreak = 10;
cc.fx.GameConfig.GM_INFO.winState = true;
cc.fx.StorageMessage.setStorage("winStreak", 10);
cc.fx.StorageMessage.setStorage("winState", true);
}
else if (data.data.winStreak !== undefined && data.data.winStreak !== null) {
// console.log("从服务器得到连胜", data.data.winStreak);
cc.fx.GameConfig.GM_INFO.winStreak = parseInt(data.data.winStreak);
let winState = cc.fx.StorageMessage.getStorage("winState");
// console.log("本地连胜状态", winState);
let noCache = (winState == null || winState == undefined) && winState != false;
if (data.data.forcedUpdate === true
|| cc.fx.GameConfig.GM_INFO.wucai_type === 1
|| noCache) {
// console.log("没有缓存进入这里 || 或者强制刷新");
cc.fx.GameConfig.GM_INFO.winState = false;
if (cc.fx.GameConfig.GM_INFO.winStreak >= 10) {
cc.fx.GameConfig.GM_INFO.winState = true;
}
cc.fx.StorageMessage.setStorage("winState", cc.fx.GameConfig.GM_INFO.winState);
}
else {
// console.log("以本地为主");
cc.fx.GameConfig.GM_INFO.winState = winState;
// console.log("连胜状态:", cc.fx.GameConfig.GM_INFO.winState);
if (winState == false) {
if (cc.fx.GameConfig.GM_INFO.winStreak >= 10) {
cc.fx.GameConfig.GM_INFO.winStreak = 0;
Utils.setWinStreak((data) => {
if (data.code == 1) {
// console.log("连胜状态杀端清零成功");
}
})
}
}
}
cc.fx.StorageMessage.setStorage("winStreak", cc.fx.GameConfig.GM_INFO.winStreak);
}
//服务器没有连胜记录,以本地为主
else {
let winStreak = cc.fx.StorageMessage.getStorage("winStreak");
if (winStreak == undefined || winStreak == "" || winStreak == null) {
cc.fx.GameConfig.GM_INFO.winStreak = 0;
cc.fx.StorageMessage.setStorage("winStreak", cc.fx.GameConfig.GM_INFO.winStreak);
}
else {
cc.fx.GameConfig.GM_INFO.winStreak = winStreak;
}
// console.log("调用连胜上传");
Utils.setWinStreak((data) => {
if (data.code == 1) {
// console.log("设置连胜成功");
}
})
}
this.setUserPower(data);
this.setmonth(data);
this.setRevive();
let levelInfo = cc.fx.StorageMessage.getStorage("level");
//如果本地缓存没有关卡信息,默认为服务器信息为主
if (levelInfo == undefined || levelInfo == "" || levelInfo == null) {
this.getUserDataToServer(data.data);
// this.oldReadData(retryCount);
}
//新的读取数据设置方法,以本地为主
else {
this.getUserDataToLocal(data.data);
// this.newReadData();
}
if (data.data.isFirst === true) {
// console.log("服务器中严格的新用户,发送注册事件和公共属性");
this.setFirstInfo();
}
if (data.data.forcedUpdate === true
|| cc.fx.GameConfig.GM_INFO.wucai_type === 1) {
const healthAmount = Number(data.data.healthAmount);
const healthTimestamp = Number(data.data.healthtimestamp);
cc.fx.GameConfig.GM_INFO.hp = Number.isFinite(healthAmount)
? healthAmount
: cc.fx.GameConfig.GM_INFO.hp_Max;
cc.fx.StorageMessage.setStorage("health", {
health: cc.fx.GameConfig.GM_INFO.hp,
timestamp: Number.isFinite(healthTimestamp) ? healthTimestamp : Date.now(),
});
}
cc.fx.GameTool.getHealth((data) => {
this.load5 = true;
});
MiniProgramBenefitsBridge.instance.onLogin(data.data);
this.load6 = true;
CloudRiseService.afterLogin();
PyramidService.resetLogin();
void ActivityScheduleService.afterLogin();
cc.fx.GameTool.iosCanPay();
}
else {
if (data.msg == "账号封禁") {
MiniGameSdk.API.showToast("账号违规,已被永久封禁", 100000);
return;
}
MiniGameSdk.API.showToast(data.msg);
if (retryCount < MAX_RETRIES && retryCount < delays.length) {
const delay = delays[retryCount];
console.error(`获取用户信息失败,第 ${retryCount + 1} 次重试,将在 ${delay / 1000} 秒后重试`);
setTimeout(() => {
retryCount++;
attemptUserInfo();
}, delay);
} else {
console.error('获取用户信息失败,达到最大重试次数,退出游戏');
// 退出游戏
cc.game.end();
}
}
}, wucaiEntryId ? 'wucai' : undefined, wucaiEntryId);
};
attemptUserInfo();
}
else {
this.load3 = true;
this.load4 = true;
this.load5 = true;
this.load6 = true;
cc.fx.GameTool.getHealth(null);
}
// 存储用户数据
}
/** 只缓存登录结果中已存在的活动状态,不在登录时创建活动数据。 */
private setJungleTreasureLoginState(userData: any): void {
const gameInfo: any = cc.fx.GameConfig.GM_INFO;
// 每次登录后由首页 read 接口重新确认本期是否可参加。
delete gameInfo.jungleTreasureAvailable;
const pendingSettlement = userData && userData.pendingJungleSettlement;
gameInfo.pendingJungleSettlement = pendingSettlement
&& typeof pendingSettlement === "object"
&& typeof pendingSettlement.settlementId === "string"
? pendingSettlement
: null;
const hasState = userData
&& Object.prototype.hasOwnProperty.call(userData, "jungleTreasureState");
if (!hasState) {
delete gameInfo.jungleTreasureState;
delete gameInfo.jungleTreasureServerNow;
return;
}
let state = userData.jungleTreasureState;
if (typeof state === "string") {
try {
state = JSON.parse(state);
}
catch (error) {
state = null;
}
}
if (!state || !Array.isArray(state.tierStates) || !isFinite(Number(state.expiresAt))) {
delete gameInfo.jungleTreasureState;
delete gameInfo.jungleTreasureServerNow;
return;
}
gameInfo.jungleTreasureState = state;
gameInfo.jungleTreasureServerNow = Number(userData.jungleTreasureServerNow) || Date.now();
}
/** 将登录返回的当前账号数据整理为选择弹窗需要的展示字段。 */
private buildWucaiCurrentPreview(userData: any): any {
const numberOrZero = (value: any): number => {
const numberValue = Number(value);
return Number.isFinite(numberValue) ? numberValue : 0;
};
let passCheck = userData && userData.passCheck;
if (typeof passCheck === "string") {
try {
passCheck = JSON.parse(passCheck);
}
catch (error) {
passCheck = null;
}
}
const passCheckActive = Array.isArray(passCheck)
? passCheck.some(item => item && (item.activate === true || item.activate === 1))
: !!passCheck && (passCheck.activate === true || passCheck.activate === 1);
return {
levelAmount: numberOrZero(userData && userData.levelAmount),
coinAmount: numberOrZero(userData && userData.coinAmount),
healthAmount: numberOrZero(userData && userData.healthAmount),
freezeAmount: numberOrZero(userData && userData.freezeAmount),
hammerAmount: numberOrZero(userData && userData.hammerAmount),
magicAmount: numberOrZero(userData && userData.magicAmount),
monthCardActive: numberOrZero(userData && userData.monthCardTime) > Math.floor(Date.now() / 1000),
passCheckActive,
};
}
private showWucaiTransfer(): boolean {
const transfer = cc.find("Canvas/Transfer");
if (!transfer) {
return false;
}
transfer.zIndex = cc.macro.MAX_ZINDEX;
transfer.active = true;
return true;
}
private loginShushuOnce(): void {
if (this.shushuLoggedIn) {
return;
}
this.shushuLoggedIn = true;
MiniGameSdk.API.shushu_Login();
const wucaiType = Number(cc.fx.GameConfig.GM_INFO.wucai_type);
const transferred = wucaiType === 0 || wucaiType === 2 || wucaiType === 3;
MiniGameSdk.API.shushu_userSetTransferredFromWucai(transferred);
if (wucaiType === 0 && this.autoWucaiLevelAmount !== null) {
MiniGameSdk.API.shushu_TrackWucaiTransfer(0, 0, this.autoWucaiLevelAmount, null);
this.autoWucaiLevelAmount = null;
}
}
//#region 读取音乐配置
/** 读取音乐配置 */
readMusicConfig() {
let audioInfo = cc.fx.StorageMessage.getStorage("music");
if (audioInfo == undefined || audioInfo == "" || audioInfo == null) {
audioInfo = {
"musicOpen": true, //音乐
"effectOpen": true, //音效
"vibrateOpen": true, //震动
}
cc.fx.StorageMessage.setStorage("music", audioInfo);
}
else {
cc.fx.GameConfig.GM_INFO.musicOpen = audioInfo.musicOpen;
cc.fx.GameConfig.GM_INFO.effectOpen = audioInfo.effectOpen;
cc.fx.GameConfig.GM_INFO.vibrateOpen = audioInfo.vibrateOpen;
}
if (cc.fx.GameTool.shouldDefaultBackgroundMusicOff()) {
cc.fx.GameConfig.GM_INFO.musicOpen = false;
audioInfo.musicOpen = false;
cc.fx.StorageMessage.setStorage("music", audioInfo);
}
}
private applyForcedProgress(data): void {
const timestamp = Date.now();
const levelAmount = Number(data.levelAmount) || 0;
const coinAmount = Number(data.coinAmount) || 0;
const freezeAmount = Number.isFinite(Number(data.freezeAmount)) ? Number(data.freezeAmount) : 3;
const hammerAmount = Number.isFinite(Number(data.hammerAmount)) ? Number(data.hammerAmount) : 3;
const magicAmount = Number.isFinite(Number(data.magicAmount)) ? Number(data.magicAmount) : 3;
cc.fx.GameConfig.GM_INFO.level = levelAmount;
cc.fx.GameConfig.GM_INFO.coin = coinAmount;
cc.fx.GameConfig.GM_INFO.freezeAmount = freezeAmount;
cc.fx.GameConfig.GM_INFO.hammerAmount = hammerAmount;
cc.fx.GameConfig.GM_INFO.magicAmount = magicAmount;
cc.fx.StorageMessage.setStorage("level", { level: levelAmount, timestamp });
cc.fx.StorageMessage.setStorage("coin", { coin: coinAmount, timestamp });
cc.fx.StorageMessage.setStorage("prop", {
freezeAmount,
hammerAmount,
magicAmount,
timestamp,
});
}
//#region 老用户,读取数据
/** 老用户,有本地缓存数据,与服务器数据做比对,哪边关卡等级高以哪边为主 */
getUserDataToLocal(data) {
let levelInfo = cc.fx.StorageMessage.getStorage("level");
let coinInfo = cc.fx.StorageMessage.getStorage("coin");
let propInfo = cc.fx.StorageMessage.getStorage("prop");
if (data.levelAmount == null || data.levelAmount == undefined) {
data.levelAmount = 0;
}
if (data.coinAmount == null || data.coinAmount == undefined) {
data.coinAmount = 0;
}
if (data.forcedUpdate === true || data.wucai_type === 1) {
this.applyForcedProgress(data);
this.load3 = true;
this.load4 = true;
return;
}
if (levelInfo.level > data.levelAmount) {
// console.log("本地等级 大于服务器等级才走这里")
cc.fx.GameConfig.GM_INFO.level = levelInfo.level;
cc.fx.GameConfig.GM_INFO.coin = coinInfo.coin;
if (propInfo != undefined && propInfo != null) {
cc.fx.GameConfig.GM_INFO.freezeAmount = propInfo.freezeAmount;
cc.fx.GameConfig.GM_INFO.hammerAmount = propInfo.hammerAmount;
cc.fx.GameConfig.GM_INFO.magicAmount = propInfo.magicAmount;
}
else {
cc.fx.GameConfig.GM_INFO.freezeAmount = data.freezeAmount;
cc.fx.GameConfig.GM_INFO.hammerAmount = data.hammerAmount;
cc.fx.GameConfig.GM_INFO.magicAmount = data.magicAmount;
}
const timestamp = Date.now();
if (coinInfo.coin != data.coinAmount) {
if ((coinInfo == undefined || coinInfo.coin == null) || data.forcedUpdate === true) {
// console.log("没有缓存进入这里 || 或者强制刷新", data.forcedUpdate);
cc.fx.GameConfig.GM_INFO.coin = data.coinAmount;
let coinInfo = { "coin": cc.fx.GameConfig.GM_INFO.coin, "timestamp": timestamp };
cc.fx.StorageMessage.setStorage("coin", coinInfo);
cc.fx.GameConfig.GM_INFO.freezeAmount = data.freezeAmount;
cc.fx.GameConfig.GM_INFO.hammerAmount = data.hammerAmount;
cc.fx.GameConfig.GM_INFO.magicAmount = data.magicAmount;
let propInfo = {
"freezeAmount": data.freezeAmount,
"hammerAmount": data.hammerAmount,
"magicAmount": data.magicAmount,
"timestamp": timestamp,
}
cc.fx.StorageMessage.setStorage("prop", propInfo);
}
else {
cc.fx.GameTool.setUserCoin((data) => {
});
}
}
if (levelInfo.level != data.levelAmount) {
// console.log("本地等级 大于服务器等级才走这里", levelInfo.level, data.levelAmount);
if ((levelInfo.level == null || levelInfo == undefined)) {
cc.fx.GameConfig.GM_INFO.level = data.levelAmount;
let levelInfo = { "level": cc.fx.GameConfig.GM_INFO.level, "timestamp": timestamp };
cc.fx.StorageMessage.setStorage("level", levelInfo);
}
else {
// console.log("往服务器传输等级");
Utils.setUserLevel((data) => {
})
}
}
if (propInfo.freezeAmount != data.freezeAmount || propInfo.hammerAmount != data.hammerAmount || propInfo.magicAmount != data.magicAmount) {
cc.fx.GameTool.setUserProp(0, 0, (data) => {
})
}
this.load3 = true;
this.load4 = true;
}
else {
const localLevel = levelInfo.level;
const serverLevelIsNewer = localLevel < data.levelAmount;
// 服务器关卡更高,说明当前设备缓存已落后,资源数据统一以服务器为准。
if (data.levelAmount == null || data.levelAmount == undefined) {
data.levelAmount = cc.fx.GameConfig.GM_INFO.level;
Utils.setUserLevel((data) => {
})
}
if (data.coinAmount == null || data.coinAmount == undefined) {
data.coinAmount = cc.fx.GameConfig.GM_INFO.coin;
cc.fx.GameTool.setUserCoin((data) => {
});
}
const timestamp = Date.now();
let levelInfoTemp = { "level": data.levelAmount, "timestamp": timestamp };
cc.fx.StorageMessage.setStorage("level", levelInfoTemp);
let coinInfoTemp = { "coin": data.coinAmount, "timestamp": timestamp };
cc.fx.StorageMessage.setStorage("coin", coinInfoTemp);
if (serverLevelIsNewer || data.forcedUpdate == true) {
let propInfo = {
"freezeAmount": data.freezeAmount,
"hammerAmount": data.hammerAmount,
"magicAmount": data.magicAmount,
"timestamp": timestamp,
}
cc.fx.GameConfig.GM_INFO.freezeAmount = data.freezeAmount;
cc.fx.GameConfig.GM_INFO.hammerAmount = data.hammerAmount;
cc.fx.GameConfig.GM_INFO.magicAmount = data.magicAmount;
cc.fx.GameConfig.GM_INFO.level = data.levelAmount;
cc.fx.GameConfig.GM_INFO.coin = data.coinAmount;
cc.fx.StorageMessage.setStorage("prop", propInfo);
if (serverLevelIsNewer) {
// console.log("服务器关卡高于本地,金币和道具已使用服务器数据覆盖本地缓存", localLevel, data.levelAmount);
}
// console.log("走的强制刷新", cc.fx.GameConfig.GM_INFO.hammerAmount)
}
else {
cc.fx.GameConfig.GM_INFO.freezeAmount = propInfo.freezeAmount;
cc.fx.GameConfig.GM_INFO.hammerAmount = propInfo.hammerAmount;
cc.fx.GameConfig.GM_INFO.magicAmount = propInfo.magicAmount;
cc.fx.GameConfig.GM_INFO.level = data.levelAmount;
cc.fx.GameConfig.GM_INFO.coin = data.coinAmount;
// console.log("走的本地缓存刷新", cc.fx.GameConfig.GM_INFO.hammerAmount)
}
this.load3 = true;
this.load4 = true;
}
}
//#region 新用户,读取数据
/** 本地没信息,新用户,或者清缓存用户 */
getUserDataToServer(data) {
const timestamp = Date.now();
if (data) {
if (data.isFirst === true) {
cc.fx.GameConfig.GM_INFO.first = true;
}
this.load3 = true;
this.load4 = true;
if (data.levelAmount == null || data.levelAmount == undefined) {
data.levelAmount = cc.fx.GameConfig.GM_INFO.level;
Utils.setUserLevel((data) => {
})
}
if (data.coinAmount == null || data.coinAmount == undefined) {
data.coinAmount = cc.fx.GameConfig.GM_INFO.coin;
cc.fx.GameTool.setUserCoin((data) => {
});
}
let levelInfo = { "level": data.levelAmount, "timestamp": timestamp };
cc.fx.StorageMessage.setStorage("level", levelInfo);
let coinInfo = { "coin": data.coinAmount, "timestamp": timestamp };
cc.fx.StorageMessage.setStorage("coin", coinInfo);
let propInfo = {
"freezeAmount": data.freezeAmount,
"hammerAmount": data.hammerAmount,
"magicAmount": data.magicAmount,
"timestamp": timestamp,
}
// console.log("不应该走到这里的的-_----------------");
cc.fx.GameConfig.GM_INFO.freezeAmount = data.freezeAmount;
cc.fx.GameConfig.GM_INFO.hammerAmount = data.hammerAmount;
cc.fx.GameConfig.GM_INFO.magicAmount = data.magicAmount;
cc.fx.GameConfig.GM_INFO.level = data.levelAmount;
cc.fx.GameConfig.GM_INFO.coin = data.coinAmount;
cc.fx.StorageMessage.setStorage("prop", propInfo);
}
}
/** 倒计时,保证进度在1秒内不进入游戏 */
startTimeCutDown() {
this.scheduleCallback = function () {
if (this.timeNumber <= 0) {
this.stopTimeCutDown();
}
else {
this.timeNumber -= 1;
}
}.bind(this);
this.schedule(this.scheduleCallback, 1);
}
/** 停止定时器 */
stopTimeCutDown() {
if (this.scheduleCallback) {
this.unschedule(this.scheduleCallback);
}
}
//#region 设置无限体力信息
/** 设置无限体力信息 */
setUserPower(data) {
let nowTime = Math.floor(Date.now() / 1000);
if (data.data.forcedUpdate === true
|| cc.fx.GameConfig.GM_INFO.wucai_type === 1) {
const serverPowerTime = Number(data.data.userPowerTime) || 0;
const effectivePowerTime = serverPowerTime > nowTime ? serverPowerTime : 0;
cc.fx.GameConfig.GM_INFO.userPowerTime = effectivePowerTime;
cc.fx.StorageMessage.setStorage("userPowerTime", effectivePowerTime);
return;
}
let powerTime = cc.fx.StorageMessage.getStorage("userPowerTime");
//本地没缓存
if (powerTime == "undifend" || powerTime == null || powerTime == "" || powerTime == 0) {
//本地没缓存,但是服务器有缓存,判断服务器的无限体力时间是否过期
if (data.data.userPowerTime && data.data.userPowerTime != 0) {
powerTime = data.data.userPowerTime;
if (powerTime > nowTime) {
cc.fx.GameConfig.GM_INFO.userPowerTime = powerTime;
cc.fx.StorageMessage.setStorage("userPowerTime", powerTime);
}
else {
cc.fx.GameConfig.GM_INFO.userPowerTime = 0;
cc.fx.StorageMessage.setStorage("userPowerTime", 0);
}
}
//本地没缓存,服务器也没缓存
else {
powerTime = 0;
cc.fx.GameConfig.GM_INFO.userPowerTime = 0;
cc.fx.StorageMessage.setStorage("userPowerTime", 0);
}
}
//本地有缓存
else {
//本地有缓存,且服务器有缓存
if (data.data.userPowerTime && data.data.userPowerTime != 0) {
//服务器缓存大于本地缓存,以服务器缓存为主
if (data.data.userPowerTime > powerTime) {
powerTime = data.data.userPowerTime;
if (powerTime > nowTime) {
cc.fx.GameConfig.GM_INFO.userPowerTime = powerTime;
cc.fx.StorageMessage.setStorage("userPowerTime", powerTime);
}
else {
cc.fx.GameConfig.GM_INFO.userPowerTime = 0;
cc.fx.StorageMessage.setStorage("userPowerTime", 0);
}
}
//服务器缓存小于本地缓存,以本地缓存为主
else {
if (powerTime > nowTime) {
cc.fx.GameConfig.GM_INFO.userPowerTime = powerTime;
cc.fx.StorageMessage.setStorage("userPowerTime", powerTime);
}
else {
cc.fx.GameConfig.GM_INFO.userPowerTime = 0;
cc.fx.StorageMessage.setStorage("userPowerTime", 0);
}
}
}
//本地有缓存,服务器没缓存
else {
if (powerTime > nowTime) {
cc.fx.GameConfig.GM_INFO.userPowerTime = powerTime;
cc.fx.StorageMessage.setStorage("userPowerTime", powerTime);
}
else {
cc.fx.GameConfig.GM_INFO.userPowerTime = 0;
cc.fx.StorageMessage.setStorage("userPowerTime", 0);
}
}
}
}
//#region 设置月卡信息
/** 设置月卡信息 */
setmonth(data) {
//如果给的时间戳大于当前时间hpmax=7,否则等于5
let nowTime = Math.floor(Date.now() / 1000);
if (data.data.monthCardTime > nowTime) {
cc.fx.GameConfig.GM_INFO.hp_Max = 7;
cc.fx.GameConfig.GM_INFO.doubleCoin = 2;
} else {
cc.fx.GameConfig.GM_INFO.hp_Max = 5;
cc.fx.GameConfig.GM_INFO.doubleCoin = 1;
}
//本地储存当前服务器时间
let dateStr = new Date(data.data.monthCardTime);
cc.fx.StorageMessage.setStorage("mCardDate", dateStr);
}
//#region 复活礼包状态初始化
/** 复活礼包不限制购买次数 */
setRevive() {
cc.fx.GameConfig.GM_INFO.revive = 0;
}
//#region 获取有没有分享信息
/** 获取有没有分享信息 */
getShareInfo() {
// 检查微信小游戏启动参数
if (cc.sys.platform === cc.sys.WECHAT_GAME || cc.sys.platform === cc.sys.BYTEDANCE_GAME) {
//@ts-ignore
const launchOptions = wx.getLaunchOptionsSync();
const query = launchOptions.query;
if (query.level && query.uid) {
const level = parseInt(query.level, 10);
const uid = query.uid;
cc.fx.GameConfig.GM_INFO.otherUid = uid;
cc.fx.GameConfig.GM_INFO.otherLevel = level;
// 可以在这里处理关卡信息和 UID
}
}
}
//#region 获取是否授权
/** 获取是否授权 */
getSetting() {
MiniGameSdk.API.getWechatUserInfo((res) => {
})
}
//第一次进游戏用户处理信息
setFirstInfo() {
const time = cc.fx.GameTool.formatDate(new Date());
let data = {
register_time: time, // 注册时间
}
cc.fx.GameTool.shushu_Track("register", data);
MiniGameSdk.API.shushu_SetSuperProperties(time, false);
MiniGameSdk.API.tencent_OnRegister();
}
//#region 获取 URL 后缀
/** 获取当前页面 URL 中 ? 后面的查询字符串(后缀) */
static getUrlSuffix(): string {
const url = window.location ? window.location.href : '';
const idx = url.indexOf('?');
return idx >= 0 ? url.substring(idx + 1) : '';
}
/** 获取 URL 后缀中指定参数名的值 */
static getUrlParam(name: string): string {
const suffix = GameManager.getUrlSuffix();
if (!suffix) return '';
const params = suffix.split('&');
for (const item of params) {
const [key, value] = item.split('=');
if (key === name) return value || '';
}
return '';
}
//#endregion
/** 主循环,判断是否各项加载完成进入游戏 */
update(dt) {
if (ClientUpdate.blocked) return;
if (this.load1 && this.load2 && this.load3 && this.load4 && this.load5 && this.load6 == true && this.timeNumber <= 0) {
this.loginShushuOnce();
if (cc.fx.GameConfig.GM_INFO.wucai_type === 1) {
if (!this.wucaiTransferShown) {
this.wucaiTransferShown = this.showWucaiTransfer();
}
return;
}
this.load1 = this.load2 = false;
if (this.shouldClearForcedUpdate) {
this.shouldClearForcedUpdate = false;
Utils.setForcedUpdate((res) => {
if (res.code !== 1) {
console.error("清除服务器强制刷新状态失败,下次登录将继续刷新", res);
}
});
}
MiniGameSdk.API.yinli_Init();
MiniGameSdk.API.yinli_Login();
this.setWX();
if (this.register_time != 0) MiniGameSdk.API.shushu_userSet(this.register_time);
MiniGameSdk.API.shushu_userSetLast(cc.fx.GameTool.formatDate(new Date()));
this.startGame();
}
}
setWX() {
//@ts-ignore
if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { // 判断是否在微信环境
//@ts-ignore
wx.setPreferredFramesPerSecond(60);
// // 设置转发按钮点击后的回调
let iphoneArr = [
"https://mmocgame.qpic.cn/wechatgame/Lf3SBqy9XpNkakoIZygRzXqww3HTibq6VyibazqmicwibjCS3YpgqbZtkdyABm4Y1wAr/0",
"https://mmocgame.qpic.cn/wechatgame/TWKuFxnCn7ksT3KXfhCC4yOfZeD4b0hrptDSJ2DFmwz02Yc8SppcwyPAOoS1MsMr/0",
"https://mmocgame.qpic.cn/wechatgame/dibaH2x79o1wSwBDymhyzXwfcyicaDb6R5icrFIO7251T4NgxIzXRXErHvAvn50vXFA/0",
"https://mmocgame.qpic.cn/wechatgame/Pgxad80d8ws3o69OicV3DTuTkcP81upQeJ0JBNS1xib3pzYLTF1ZqGY3niciaI7ICKlL/0",
"https://mmocgame.qpic.cn/wechatgame/SfB1vrRBIHKn9ffKFt5sib62yPLE31m2rCvk6DKlEicJNVZSoryEObD6ItwsQn4xibR/0",
"https://mmocgame.qpic.cn/wechatgame/OiaWk33I6QjgWiatrb5YVUq2p0QRmQgO6rLUWxEQDZ4ib9Ny4Pr8iaHnHI6WdxibY2nPL/0",
"https://mmocgame.qpic.cn/wechatgame/CG5xBibollws251aYD4msEPWCiafrcn4Fgtic4T2wME6sWmdfAUtfibgsWoxm59VadDD/0"
]
let randomIphone = iphoneArr[Math.floor(Math.random() * iphoneArr.length)];
let img = randomIphone;
// const title =
// 构建分享参数
const shareParams = {
title: '快来一起玩这个超有趣的小游戏吧!', // 修改为默认分享标题
imageUrl: 'https://example.com/default_share_image.jpg' // 修改为默认分享图片
};
//@ts-ignore
// 仅设置分享内容,不主动触发分享
wx.onShareAppMessage(() => {
DailyTaskProgressTracker.recordShare();
return shareParams;
});
// 监听分享到朋友圈事件
//@ts-ignore
wx.onShareTimeline(() => {
DailyTaskProgressTracker.recordShare();
return {
title: '你想玩上怎样的游戏?'
};
});
//@ts-ignore
wx.showShareMenu(() => {
return {
title: '你想玩上怎样的游戏?',
imageUrl: img,
query: ''
};
});
setTimeout(() => {
//@ts-ignore
wx.showShareMenu({
menus: ['shareAppMessage', 'shareTimeline']
})
}, 2000);
setTimeout(() => {
//@ts-ignore
wx.showShareMenu({
menus: ['shareAppMessage', 'shareTimeline']
})
}, 4000);
//@ts-ignore
wx.onAddToFavorites(() => {
// console.log("收藏成功");
MiniGameSdk.API.tencent_ADD_TO_WISHLIST();
return {
title: '收藏标题',
imageUrl: '' // 图片 URL
}
})
// 设置分享到朋友圈
//@ts-ignore
// wx.updateShareMenu({
// withShareTicket: true,
// success: (data) => {
// console.log('更新分享菜单成功', data);
// },
// fail: (data) => {
// console.log('更新分享菜单失败', data);
// },
// complete: (data) => {
// console.log('更新分享菜单完成', data);
// }
// });
//@ts-ignore
}
}
}