import { MiniGameSdk } from "../../Sdk/MiniGameSdk"; import { normalizePass, mergePassInfo, legacyPassInfo, legacyExperience, passTier, PASS_PERIOD } from '../Config/BattlePassModel'; //#region 测试 /** 测试 */ export default class Utils { static uid: string = ""; static session_key = ""; static appid: string = ""; static openid: string = ""; static outTradeNo: string = ""; // static httpip: string = `https://laf.nika4games.com/`; //五彩消消乐 static httpip: string = `https://q6rvwvtnga.sealoshzh.site/`; //消消王者 static testHttpip: string = `https://sor779u2w8.sealoshzh.site/`; //测试服务器 // static testHttpip: string = `https://q6rvwvtnga.sealoshzh.site/`; //消消王者测试服暂替 //#region 安卓支付 /**获取用户信息*/ static getUserInfo(callBack, from?: string) { //微信登录 if (MiniGameSdk.isWechat()) { //@ts-ignore wx.login({ success(res) { console.log("微信login成功"); let restart = 0; //console.log(res.code); if (res.code) { // 标志位,用于记录 callBack 是否已经被调用 let isCallBackCalled = false; // 定义轮询函数 const pollLogin = () => { if (isCallBackCalled) { console.log("回调已被调用,不再发起请求"); return; } let isDebug = false; let test = cc.fx.GameTool.getWechatGameVersion(); if (test == "正式版") { isDebug = true; } console.log("___________发起登录请求", isDebug); const loginData: any = { code: res.code, isDebug: isDebug, distinctId: cc.fx.GameConfig.GM_INFO.shushu_DistinctId, wucai_capability: 1, passVersion: 2, }; if (from === "wucai") { loginData.from = from; } Utils.POST("login", loginData, ret => { console.log("__________请求结果:", ret); if (!isCallBackCalled) { isCallBackCalled = true; if (ret.code === 1) { // 假设返回 code 为 1 表示成功 Utils.openid = ret.data.openid; Utils.session_key = ret.data.session_key; Utils.uid = ret.data._id; } callBack(ret); } }); // 如果回调未调用,6 秒后再次请求 if (!isCallBackCalled) { restart++; if (restart > 10) { MiniGameSdk.API.showToast("网络异常,请稍后尝试重新登录"); console.log("登录失败,重试次数超过5次"); cc.fx.GameTool.trackErrorToShushu({ message: "登录失败,重试次数超过5次" }) } setTimeout(pollLogin, 6000); } }; // 首次调用轮询函数 pollLogin(); } else { console.log('登录失败!' + res.errMsg) callBack({ code: 0, data: { openid: "登录失败" }, message: res.errMsg }); } } }) } //字节登录 else if (MiniGameSdk.isBytedance()) { //@ts-ignore tt.login({ success(res) { console.log("字节login成功"); //console.log(res.code); } }) } } //#region 道具直购接口 /**道具直购接口*/ static buyProp(id, count, price, systemType, productId, callBack, passEnd?: string) { let postName = "wx/orderPaySig"; if (systemType == "ios") { postName = "wx/iosorderPaySig"; } console.log("请求uid:" + Utils.uid, "请求id:" + id, "请求数量:" + count, "请求价格:" + price, "请求链接:" + postName); Utils.POST(postName, { uid: Utils.uid, itemid: id, itemCount: count, itemPrice: price, ...(passEnd ? { passVersion: 2, passEnd } : {}) }, res => { if (res.code == 1) { Utils.outTradeNo = res.data.outTradeNo; const passOrder = res.data.outTradeNo; const data = { outTradeNo: res.data.outTradeNo, price: price, payment_name: productId, payment_num: 1, type: systemType, } cc.fx.GameTool.shushu_Track("init_order", data); //console.log("创建的最新订单的订单号:", Utils.outTradeNo); // let timeoutId: number; // const timeoutDuration = 30000; // 30 秒超时时间 // // 设置超时定时器 // timeoutId = setTimeout(() => { // console.error('支付请求超时'); // callBack("请求支付超时"); // }, timeoutDuration); const orderNumber = res.data.outTradeNo; //@ts-ignore wx.requestMidasPaymentGameItem({ signData: res.data.signData, paySig: res.data.paySig, signature: res.data.signature, success(res, errCode) { // clearTimeout(timeoutId); // 清除超时定时器 //console.log('成功', res, errCode); callBack({ ...res, outTradeNo: orderNumber }); }, fail({ errMsg, errCode }) { // clearTimeout(timeoutId); // 清除超时定时器 //console.log('失败'); //console.log(errMsg, errCode) let data = { errMsg: errMsg, errCode: errCode, err: "请求支付失败", } callBack(data); } }) } else { callBack({ err: "创建订单失败", errCode: -1, errMsg: res.msg || "创建订单失败,请重试" }); } }); } //#region 安卓获取支付结果 /** 安卓获取支付结果 */ static getPayInfo(callBack, order: string = Utils.outTradeNo, options?: { timeoutMs: number; onProgress?: (response: any) => void }) { // 延迟时间数组,按照 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) ]; let attempt = 0; // 轮询次数 let completed = false; let retryTimer = null; let deadlineTimer = null; const finish = (response) => { if (completed) return; completed = true; clearTimeout(retryTimer); clearTimeout(deadlineTimer); callBack(response); }; const timeout = () => { if (completed) return; MiniGameSdk.API.showToast(options ? "支付结果尚未确认,请稍后重新领取" : "网络异常,如付款成功,重进游戏可领取奖励"); finish({ code: 0, data: { pay_state: -1 }, message: '轮询超时' }); }; if (options?.timeoutMs > 0) deadlineTimer = setTimeout(timeout, options.timeoutMs); const poll = () => { if (completed) return; if (attempt >= delays.length) { timeout(); return; } //console.log("请求uid:", Utils.uid); //console.log("outTradeNo:", Utils.outTradeNo); Utils.POST("wx/getPayInfo", { uid: Utils.uid, outTradeNo: order }, res => { if (completed) return; if (options?.onProgress) options.onProgress(res); if (res?.code === 1 && (res.data?.pay_state === 1 || res.data?.pay_state === 2)) { finish(res); } else { attempt++; retryTimer = setTimeout(poll, delays[attempt - 1]); } }); }; poll(); } //#region 上传领取充值奖励 /**上传领取充值奖励 */ static setPayInfo(callBack, order) { const delays = [3000, 3000, 6000, 9000, 12000, 15000, 18000, 21000];// 延迟时间数组 let attempt = 0; // 重试次数 const sendRequest = () => { if (attempt > delays.length) { // 达到最大重试次数,调用回调并返回错误信息 callBack({ code: 0, message: '请求失败,已达到最大重试次数' }); return; } let orderTemp = Utils.outTradeNo; if (order) orderTemp = order; //console.log("告知服务器发货的订单号:", orderTemp); Utils.POST("wx/getOrderReward", { outTradeNo: orderTemp, uid: cc.fx.GameConfig.GM_INFO.uid }, res => { //console.log("告知服务器发货:", res); if (res.code === 1) { console.log("告知服务器发货成功:", res); // 请求成功,调用回调并返回结果 callBack(res); } else { // 请求失败,增加重试次数并设置下一次请求的延迟 console.log("告知服务器发货失败:", res); attempt++; if (attempt <= delays.length) { setTimeout(sendRequest, delays[attempt - 1]); } else { callBack({ code: 0, message: '请求失败,已达到最大重试次数' }); } } }); }; sendRequest(); } //#region ios支付 /**跳转客服,ios支付*/ static GoKEFu(iosPayInfo, callBack) { console.log("创建新的订单,清空老订单"); var order = `wcx_` + Math.round(Math.random() * 10 ** 13) + Date.now(); if (iosPayInfo.payment_name == "month_Card") { cc.fx.GameConfig.GM_INFO.iosMonthOrder = null; cc.fx.GameConfig.GM_INFO.iosMonthOrder = order; } else if (iosPayInfo.payment_name == "reborn_Gift") { cc.fx.GameConfig.GM_INFO.iosReviveOrder = null; cc.fx.GameConfig.GM_INFO.iosReviveOrder = order; } else if (iosPayInfo.payment_name == "starter_pack") { cc.fx.GameConfig.GM_INFO.iosStarterOrder = null; cc.fx.GameConfig.GM_INFO.iosStarterOrder = order; } else if (/^battlepass(?:_30|_12)?$/.test(iosPayInfo.payment_name)) { cc.fx.GameConfig.GM_INFO.iosPassCheckOrder = null; cc.fx.GameConfig.GM_INFO.iosPassCheckOrder = order; } else if (/^jungle_treasure_\d+$/.test(String(iosPayInfo.payment_name || ""))) { cc.fx.GameConfig.GM_INFO.iosJungleOrder = null; cc.fx.GameConfig.GM_INFO.iosJungleOrder = order; } else { cc.fx.GameConfig.GM_INFO.iosShopOrder = null; cc.fx.GameConfig.GM_INFO.iosShopOrder = order; } const data = { tpye: "ios", outTradeNo: order, propName: iosPayInfo.payment_name, count: iosPayInfo.payment_count, price: iosPayInfo.price,//价格单位是分 ...(iosPayInfo.passEnd ? { passEnd: iosPayInfo.passEnd, passVersion: 2 } : {}), } const shushu_data = { outTradeNo: order, price: iosPayInfo.price, payment_name: iosPayInfo.payment_name, payment_num: iosPayInfo.payment_count, type: "ios", } console.log("________ios创建订单信息:", data); cc.fx.GameTool.shushu_Track("init_order", shushu_data); //@ts-ignore wx.openCustomerServiceConversation({ sessionFrom: JSON.stringify(data), // 会话来源(可选) showMessageCard: false, // 是否展示消息卡片 success() { callBack("success"); console.log('客服会话已successr'); }, fail() { console.log('客服会话已over'); callBack("fail"); } }); } //#region ios获取支付结果 /** ios获取支付结果 */ static getIosPayInfo(order, callBack) { // 延迟 0.5 秒执行后续逻辑 setTimeout(() => { // 最大重试次数 const maxRetries = 7; let retryCount = 0; // 标志位,用于记录 callBack 是否已经被调用 let isCallBackCalled = false; const makeRequest = () => { if (retryCount > maxRetries) { if (!isCallBackCalled) { MiniGameSdk.API.showToast("网络异常,如充值成功,重进游戏可领取奖励"); callBack({ code: 2, data: null, message: '轮询超时,达到最大重试次数' }); isCallBackCalled = true; } return; } // 设置超时定时器 const timeoutId = setTimeout(() => { retryCount++; console.log(`请求超时,第 ${retryCount} 次重新申请接口`); makeRequest(); }, 4000); const orderNow = order; console.log("请求uid:" + Utils.uid); console.log("outTradeNo:" + orderNow); Utils.POST("wx/iosgetPayInfo", { outTradeNo: orderNow, uid: cc.fx.GameConfig.GM_INFO.uid }, res => { console.log("查询字符结果IOS"); console.log(res); // 清除超时定时器 clearTimeout(timeoutId); if (!isCallBackCalled) { callBack(res); isCallBackCalled = true; } }); }; makeRequest(); }, 1000); } //#region POST请求 /** * POST请求 * * @static * @param {*} url * @param {object} [param={}] * @param {*} callback * @memberof HttpUtil */ public static POST(url, param: object | any, callback) { var xhr = cc.loader.getXMLHttpRequest(); xhr.timeout = 5000;//超时时间 let completed = false; const finish = (response) => { if (completed) return; completed = true; callback(response); }; const networkFailure = () => finish({ code: 0, data: null, msg: "网络请求失败,请重试" }); xhr.onerror = networkFailure; xhr.ontimeout = networkFailure; xhr.onabort = networkFailure; let dataStr = ''; let isDebug = false; param.token = cc.fx.GameConfig.GM_INFO.token; let test = cc.fx.GameTool.getWechatGameVersion(); if (test == "正式版") { isDebug = true; } const requestHttpip = test == "开发版" || test == "体验版" ? this.testHttpip : this.httpip; param.isDebug = isDebug; Object.keys(param).forEach(key => { dataStr += key + '=' + encodeURIComponent(param[key]) + '&'; }) if (dataStr !== '') { dataStr = dataStr.substr(0, dataStr.lastIndexOf('&')); } if (url != "getSRank" && url != "getRank") { url = requestHttpip + url; } else { url = "https://bx7gi3d4oq.sealoshzh.site/" + url; } if (url == requestHttpip + "getAddressRankOther") { url = "https://laf.nika4games.com/getAddressRank"; } else if (url == requestHttpip + "getAddressRankSelf") { url = requestHttpip + "getAddressRank"; } xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.onreadystatechange = function () { if (xhr && xhr.readyState) { if (xhr.readyState === 4) { let response: any = xhr.responseText; if (xhr.status >= 200 && xhr.status < 300) { // callback(true, JSON.parse(response)); try { response = JSON.parse(response); } catch { response = { data: null, code: 0, msg: "数据有误" }; } if (response.code == 0) { if (response.msg === "token校验失败") { if (MiniGameSdk) { MiniGameSdk.API.showToast("游戏已更新,请关闭游戏重新进入"); } } } finish(response); } else { networkFailure(); } } } }; xhr.send(dataStr); } //#region 获取用户数据 /** 获取用户数据,包含头像昵称注册时间 */ static getUserData(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let data = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("userData", data, res => { //console.log("获得userData数据:", res); if (res.code === 1) { //console.log("服务器:获取用户数据成功", res); if (callBack) callBack(res); } else { //console.log("服务器:获取用户数据失败", res); if (callBack) callBack(res); } }); } } //#region 上传用户信息 /** 上传用户信息 */ static setUserData(data, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', userData: JSON.stringify(data) } console.log("准备上传头像昵称最后一步", data); Utils.POST("userData", setData, res => { // console.log("获得userData数据:", res); if (res.code === 1) { console.log("服务器:获取用户数据成功", res); if (callBack) callBack(res); } else { //console.log("服务器:获取用户数据失败", res); if (callBack) callBack(res); } }); // useravatar:userData1.useravatar||Math.floor(Math.random()*4)+"", // username:userData1.username||"user", // useravatarIcon: userData1.useravatarIcon||"0", } } //#region 金币,等级,道具,体力 /** 获得金币信息 */ static getUserCoin(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("userCoin", setData, res => { //console.log("获得userCoin数据:", res); if (res.code === 1) { //console.log("服务器:获得金币成功", res); if (callBack) callBack(res); } else { //console.log("服务器:获得金币失败", res); if (callBack) callBack(res); } }); } } /** 上传金币信息 */ //上传金币信息 static setUserCoin(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } if (cc.fx.GameConfig.GM_INFO.coin <= 0 || cc.fx.GameConfig.GM_INFO.coin == undefined) { cc.fx.GameConfig.GM_INFO.coin = 0; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', coinAmount: Math.floor(cc.fx.GameConfig.GM_INFO.coin) } //console.log("服务器:上传金币", Math.floor(cc.fx.GameConfig.GM_INFO.coin)); Utils.POST("userCoin", setData, res => { //console.log("获得userCoin数据:", res); if (res.code === 1) { //console.log("服务器:上传金币成功", res); if (callBack) callBack(res); } else { //console.log("服务器:上传金币失败", res); if (callBack) callBack(res); } }); } } /** 获得关卡等级信息 */ //获得关卡等级信息 static getUserLevel(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("userLevel", setData, res => { //console.log("获得userLevel数据:", res); if (res.code === 1) { if (res.data && res.data.film !== undefined) { cc.fx.GameConfig.GM_INFO.film = Number(res.data.film); } //console.log("服务器:获得等级成功", res); if (callBack) callBack(res); } else { //console.log("服务器:获得等级失败", res); if (callBack) callBack(res); } }); } } /** 上传关卡等级信息 */ //上传关卡等级信息 static setUserLevel(callBack, wuxian?) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } if (cc.fx.GameConfig.GM_INFO.level <= 0 || cc.fx.GameConfig.GM_INFO.level == undefined) { cc.fx.GameConfig.GM_INFO.level = 0; } let isWuxian = wuxian !== undefined ? wuxian : false; // 如果wuxian有传值则使用该值,否则默认为false let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', levelAmount: parseInt(cc.fx.GameConfig.GM_INFO.level), isWuXian: isWuxian } console.log("无限值", isWuxian); Utils.POST("userLevel", setData, res => { //console.log("获得userLevel数据:", res); if (res.code === 1) { if (res.data && res.data.film !== undefined) { cc.fx.GameConfig.GM_INFO.film = Number(res.data.film); } //console.log("服务器:上传等级成功", res); if (callBack) callBack(res); } else { //console.log("服务器:上传等级失败", res); if (callBack) callBack(res); } }); } } /** 获得用户道具信息 */ //获得用户道具信息 static getUserProp(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("userProp", setData, res => { //console.log("获得userProp数据:", res); if (res.code === 1) { //console.log("服务器:获得道具成功", res); if (callBack) callBack(res); } else { //console.log("服务器:获得道具失败", res); if (callBack) callBack(res); } }); } } /** 上传道具信息 */ //上传道具信息 static setUserProp(propid, amount, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = null; if (propid == 0) { setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', propType: propid, propData: JSON.stringify(amount), } } else { setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', propType: propid, propData: amount, } } //console.log("上传道具类型", propid, "上传道具数量:", amount); Utils.POST("userProp", setData, res => { //console.log("获得userProp数据:", res); if (res.code === 1) { //console.log("服务器:上传道具成功", res); if (callBack) callBack(res); } else { //console.log("服务器:上传道具失败", res); if (callBack) callBack(res); } }); } } /** 获取体力信息 */ static getUserHealth(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("userHealth", setData, res => { //console.log("获得userHealth数据:", res); if (res.code === 1) { //console.log("服务器:获得体力成功", res); if (callBack) callBack(res); } else { //console.log("服务器:获得体力失败", res); if (callBack) callBack(res); } }); } } /** 上传体力信息 */ //上传关卡等级信息 static setUserHealth(timestamp, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', healthAmount: cc.fx.GameConfig.GM_INFO.hp, timestamp: timestamp } Utils.POST("userHealth", setData, res => { //console.log("获得userHealth数据:", res); if (res.code === 1) { //console.log("服务器:上传体力成功", res); if (callBack) callBack(res); } else { //console.log("服务器:上传体力失败", res); if (callBack) callBack(res); } }); } } //#region 无限体力相关 /** 获取无限体力信息 */ static getUserPowerTime(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("userPower", setData, res => { //console.log("获得userPower数据:", res); if (res.code === 1) { //console.log("服务器:获得无限体力成功", res); if (callBack) callBack(res); } else { //console.log("服务器:获得无限体力失败", res); if (callBack) callBack(res); } }); } } /** 上传无限体力信息 */ static setUserPowerTime(userPowerTime, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', userPowerTime: userPowerTime } Utils.POST("userPower", setData, res => { //console.log("获得userPower数据:", res); if (res.code === 1) { //console.log("服务器:上传无限体力成功", res); if (callBack) callBack(res); } else { //console.log("服务器:上传无限体力失败", res); if (callBack) callBack(res); } }); } } //#region 月卡相关 /** 获得月卡奖励信息 */ static monthGetReward(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, } Utils.POST("monthGetReward", setData, res => { // //console.log("获得monthGetReward数据:", res); if (res.code === 1) { // //console.log("服务器:领取获得monthGetReward成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:获得monthGetReward失败'❌ ", res); if (callBack) callBack(res); } }); } } /** 获得月卡信息 */ static getMonthlyCard(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); // //console.log("获取monthlyCard信息:", uid, monthCardTime); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("monthlyCard", setData, res => { // //console.log("获得monthlyCard数据:", res); if (res.code === 1) { // //console.log("服务器:获取monthlyCard成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:获取monthlyCard失败'❌ ", res); if (callBack) callBack(res); } }); } } /** 上传月卡信息 */ //上传monthlyCard信息 static setMonthlyCard(monthCardTime, callBack, outTradeNo?: string) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); // //console.log("上传monthlyCard信息:", uid, monthCardTime); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', monthCardTime: monthCardTime, outTradeNo: outTradeNo || Utils.outTradeNo, } Utils.POST("monthlyCard", setData, res => { // //console.log("获得monthlyCard数据:", res); if (res.code === 1) { // //console.log("服务器:上传monthlyCard成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:上传monthlyCard失败'❌ ", res); if (callBack) callBack(res); } }); } } //#region 复活礼包相关 /** 是否还有复活礼包出现机会 */ static canRebonGift(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, } Utils.POST("canRebornGift", setData, res => { if (res.code === 1) { //console.log("服务器:canRebonGift'✅ ", res); if (callBack) callBack(res); } else { if (callBack) callBack(res); } }); } } /** 购买复活礼包后上传 */ //上传monthlyCard信息 static rebornGift(rebornGift, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); // //console.log("上传monthlyCard信息:", uid, monthCardTime); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', rebornGift: rebornGift, } Utils.POST("rebornGift", setData, res => { // //console.log("获得rebornGift数据:", res); if (res.code === 1) { //console.log("服务器:上传rebornGift成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:上传rebornGift失败'❌ ", res); if (callBack) callBack(res); } }); } } //#region 分享相关 //设置分享成功信息,帮别人成功 static shareLevel(otherLevel, uid, callBack) { let otheruid = uid || ""; let level = otherLevel || 0; let data = { uid: otheruid, otherUid: cc.fx.GameConfig.GM_INFO.uid, shareLv: level, }; // 延迟时间数组,按照 1 秒 3 次、2 秒 5 次、5 秒 6 次、15 秒 5 次的规则生成 const delays = [ ...Array(3).fill(1000), ...Array(5).fill(2000), ...Array(6).fill(5000), ...Array(5).fill(15000) ]; let attempt = 0; // 轮询次数 const poll = () => { if (attempt >= delays.length) { MiniGameSdk.API.showToast("网络异常,分享数据提交失败"); callBack({ code: 0, data: null, message: '轮询超时' }); return; } Utils.POST("shareLvSuccess", data, res => { console.log("获得shareLvSuccess数据:", res); if (res.code === 1) { //console.log("服务器:分享帮助通过关卡数据成功", res); callBack(res); } else { attempt++; setTimeout(poll, delays[attempt - 1]); } }); }; poll(); } /** 获取分享信息 */ //获取分享信息 static getShareLevel(callBack) { let data = { uid: cc.fx.GameConfig.GM_INFO.uid }; //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { Utils.POST("getShareLv", data, res => { console.log("获得shareLvSuccess数据:", res); if (res.code === 1) { console.log("服务器:分享帮助通过关卡数据成功", res); if (callBack) callBack(res); } else { if (callBack) callBack(res); } }); } } //#region 排行榜相关 /** 获取世界排行榜 */ static getRank(callBack) { // 最大重试次数 const maxRetries = 5; let retryCount = 0; // 标志位,用于记录 callBack 是否已经被调用 let isCallBackCalled = false; const makeRequest = () => { if (retryCount > maxRetries) { if (!isCallBackCalled) { MiniGameSdk.API.showToast("网络异常,如充值成功,重进游戏可领取奖励"); callBack({ code: 2, data: null, message: '轮询超时,达到最大重试次数' }); isCallBackCalled = true; } return; } // 设置超时定时器 const timeoutId = setTimeout(() => { retryCount++; console.log(`请求超时,第 ${retryCount} 次重新申请接口`); makeRequest(); }, 3000); console.log("请求uid:" + Utils.uid); Utils.POST("getRank", { uid: cc.fx.GameConfig.GM_INFO.uid }, res => { //console.log("查询排行榜结果"); //console.log(res); // 清除超时定时器 clearTimeout(timeoutId); if (!isCallBackCalled) { callBack(res); isCallBackCalled = true; } }); }; makeRequest(); } /** 获取入职排行榜 */ static getSRank(callBack) { // 最大重试次数 const maxRetries = 5; let retryCount = 0; // 标志位,用于记录 callBack 是否已经被调用 let isCallBackCalled = false; const makeRequest = () => { if (retryCount > maxRetries) { if (!isCallBackCalled) { MiniGameSdk.API.showToast("网络异常,获取排行失败"); callBack({ code: 2, data: null, message: '轮询超时,达到最大重试次数' }); isCallBackCalled = true; } return; } // 设置超时定时器 const timeoutId = setTimeout(() => { retryCount++; console.log(`请求超时,第 ${retryCount} 次重新申请接口`); makeRequest(); }, 3000); console.log("请求uid:" + Utils.uid); Utils.POST("getSRank", { uid: cc.fx.GameConfig.GM_INFO.uid }, res => { // 清除超时定时器 clearTimeout(timeoutId); if (!isCallBackCalled) { callBack(res); isCallBackCalled = true; } }); }; makeRequest(); } //#region 丛林宝藏活动 /** 获取丛林宝藏配置和玩家档位状态 */ static getJungleTreasure(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("jungleTreasure", setData, res => { console.log("获得丛林宝藏数据:", res); if (callBack) callBack(res); }); } } /** 领取丛林宝藏指定档位,tierId 从 1 开始 */ static claimJungleTreasure(tierId, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'claim', tierId: tierId, } Utils.POST("jungleTreasure", setData, res => { console.log("领取丛林宝藏数据:", res); if (callBack) callBack(res); }); } } /** 到期批量结算:资源基数来自客户端,奖励数量由服务端配置计算。 */ static settleExpiredJungleTreasure(resources, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } Utils.POST("jungleTreasure", { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'settle_expired', resources: JSON.stringify(resources), }, res => { console.log("结算到期丛林宝藏:", res); if (callBack) callBack(res); }); } } /** 玩家关闭汇总弹窗后确认结算;重复确认由服务端按成功处理。 */ static ackJungleTreasureSettlement(settlementId, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } Utils.POST("jungleTreasure", { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'ack_settlement', settlementId: settlementId, }, res => { console.log("确认丛林宝藏结算:", res); if (callBack) callBack(res); }); } } //#region 新手礼包相关 static reactivateStarter_pack(reason: string, failureCount: number, lastShownAt: number, callBack) { Utils.POST("limitedTimeEvent", { uid: cc.fx.GameConfig.GM_INFO.uid, event: "starter_pack", action: "reactivate", reason, failureCount, level: cc.fx.GameConfig.GM_INFO.level, lastShownAt, }, callBack); } static markStarterPackShown(expiry: number) { Utils.POST("limitedTimeEvent", { uid: cc.fx.GameConfig.GM_INFO.uid, event: "starter_pack", action: "shown", expiry, }, () => { }); } //获取新手礼包是否能显示 static getStarter_pack(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', event: "starter_pack", } Utils.POST("limitedTimeEvent", setData, res => { console.log("获得新手礼包数据:", res); if (res.code === 1) { // //console.log("服务器:领取获得monthGetReward成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:获得monthGetReward失败'❌ ", res); if (callBack) callBack(res); } }); } } //触发新手礼包事件 static setStarter_pack(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', event: "starter_pack", } Utils.POST("limitedTimeEvent", setData, res => { console.log("触发新手礼包事件:", res); if (res.code === 1) { console.log("服务器:领取获得monthGetReward成功'✅ ", res); if (callBack) callBack(res); } else { console.log("服务器:获得monthGetReward失败'❌ ", res); if (callBack) callBack(res); } }); } } //每日任务获取 static getDailyQuestInfo(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("dayTaskInfo", setData, res => { console.log("获取每日任务信息:", res); if (res.code === 1) { // //console.log("服务器:领取获得monthGetReward成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:获得monthGetReward失败'❌ ", res); if (callBack) callBack(res); } }); } } //设置每日任务信息 static setDailyQuestInfo(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let tasks = { levelPass: { value: cc.fx.GameConfig.GM_INFO.tasks.levelPass.value }, share: { value: cc.fx.GameConfig.GM_INFO.tasks.share.value }, useEnergy: { value: cc.fx.GameConfig.GM_INFO.tasks.useEnergy.value }, useProp: { value: cc.fx.GameConfig.GM_INFO.tasks.useProp.value } } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', task: JSON.stringify(tasks), } Utils.POST("dayTaskInfo", setData, res => { if (res.code === 1) { const task = res.data && res.data.task; if (task && task["levelPass"]) cc.fx.GameConfig.GM_INFO.tasks.levelPass = task["levelPass"]; if (task && task["share"]) cc.fx.GameConfig.GM_INFO.tasks.share = task["share"]; if (task && task["useEnergy"]) cc.fx.GameConfig.GM_INFO.tasks.useEnergy = task["useEnergy"]; if (task && task["useProp"]) cc.fx.GameConfig.GM_INFO.tasks.useProp = task["useProp"]; // //console.log("服务器:领取获得monthGetReward成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:获得monthGetReward失败'❌ ", res); if (callBack) callBack(res); } }); } } //获取每日任务奖励 static getDailyQuestReward(data, callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, taskType: JSON.stringify(data) } Utils.POST("getTaskReward", setData, res => { if (res.code === 1) { const task = res.data && res.data.task; if (task && task["levelPass"]) cc.fx.GameConfig.GM_INFO.tasks.levelPass = task["levelPass"]; if (task && task["share"]) cc.fx.GameConfig.GM_INFO.tasks.share = task["share"]; if (task && task["useEnergy"]) cc.fx.GameConfig.GM_INFO.tasks.useEnergy = task["useEnergy"]; if (task && task["useProp"]) cc.fx.GameConfig.GM_INFO.tasks.useProp = task["useProp"]; // //console.log("服务器:领取获得monthGetReward成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:获得monthGetReward失败'❌ ", res); if (callBack) callBack(res); } }); } } //设置连胜次数 static setWinStreak(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', winStreak: cc.fx.GameConfig.GM_INFO.winStreak, } Utils.POST("setWinStreak", setData, res => { if (res.code === 1) { // //console.log("服务器:领取获得monthGetReward成功'✅ ", res); if (callBack) callBack(res); } else { // //console.log("服务器:获得monthGetReward失败'❌ ", res); if (callBack) callBack(res); } }); } } //获取通行证等级 static getpassCheckLv(callBack) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("passCheckLv", setData, res => { if (res.code === 1) { console.log("请求通行证等级成功:", res); if (callBack) callBack(res); } else { console.log("请求通行证等级失败:", res); if (callBack) callBack(res); } }); } } //设置通行证等级 static setPassCheckLv(callBack, data) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } // let data = { // progress: 2, // progressLevel: 3, // } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', passCheckLv: JSON.stringify(data), } console.log("设置通行证等级数据:", setData); Utils.POST("passCheckLv", setData, res => { if (res.code === 1) { console.log("设置通行证等级成功", res); if (callBack) callBack(res); } else { console.log("设置通行证等级失败", res); } }) } } //获取通行证信息 private static passGiftPending: { [order: string]: 'pending' | 'applied' } = {}; private static applyPassGift(order: string) { const key = (cc.fx.GameConfig.GM_INFO.uid || Utils.uid) + ':' + order; if (Utils.passGiftPending[key] !== 'pending') return; Utils.passGiftPending[key] = 'applied'; cc.fx.GameConfig.GM_INFO.coin += 3000; cc.fx.StorageMessage.setStorage('coin', { coin: cc.fx.GameConfig.GM_INFO.coin, timestamp: Date.now() }); } static getPassCheckInfo(callBack) { if (!cc.fx.GameConfig.PASS_CHECK || !cc.fx.GameConfig.PASS_CHECK_OLD) { if (callBack) callBack({ code: 0, msg: '战令配置尚未加载,请稍后重试' }); return; } Utils.POST("passCheck", { uid: cc.fx.GameConfig.GM_INFO.uid || Utils.uid, action: 'read' }, res => { if (res.code !== 1) { if (callBack) callBack(res); return; } Utils.passRequest('read').then(extra => { const raw = typeof extra.data.legacy === 'string' ? JSON.parse(extra.data.legacy) : extra.data.legacy; const pass = mergePassInfo(raw, extra.data.extra, cc.fx.GameConfig.PASS_CHECK, cc.fx.GameConfig.PASS_CHECK_OLD); if (pass) { pass.revision = extra.data.revision; pass.upgradeReady = true; } for (const time of Object.keys(extra.data.extra || {})) for (const order of extra.data.extra[time].orders || []) Utils.applyPassGift(order); res.data.passCheck = JSON.stringify(pass); res.data.upgradeReady = true; if (callBack) callBack(res); }).catch(() => { if (callBack) callBack(res); }); }); } //设置通行证信息 static setPassCheckInfo(callBack, data) { if (data == null) { Utils.POST('passCheck', { uid: cc.fx.GameConfig.GM_INFO.uid || Utils.uid, action: 'save', passCheck: 'null' }, callBack || (() => { })); return; } const save = async () => { if (!data) throw { code: 0, msg: '战令数据为空' }; let pass = data; for (let attempt = 0; attempt < 3; attempt++) { const latest = await Utils.passRequest('read'); const merged = mergePassInfo(JSON.parse(latest.data.legacy || 'null'), latest.data.extra, cc.fx.GameConfig.PASS_CHECK, cc.fx.GameConfig.PASS_CHECK_OLD); for (const key of [1, 2]) { if (!pass[key] || !Number(pass[key].time)) continue; pass[key] = normalizePass(pass[key], key === 1 ? cc.fx.GameConfig.PASS_CHECK_OLD : cc.fx.GameConfig.PASS_CHECK); const current = merged && [merged[1], merged[2]].find(s => String(s && s.time) === String(pass[key].time)); if (current) { pass[key].experience = Math.max(pass[key].experience, current.experience); for (const lane of ['free', 'passCheck']) for (let i = 0; i < current[lane].length; i++) { if (current[lane][i] === 0) pass[key][lane][i] = 0; } pass[key] = normalizePass(pass[key], key === 1 ? cc.fx.GameConfig.PASS_CHECK_OLD : cc.fx.GameConfig.PASS_CHECK); } } try { return await Utils.passRequest('save', { ...Utils.passUpload(pass), revision: latest.data.revision }); } catch (error) { if (error.code !== 409 || attempt === 2) throw error; } } }; save().then(res => { if (callBack) callBack(res); }, error => { if (callBack) callBack(error); }); } /** 只用于战令接口,避免网络无回调时卡住本次战令操作。 */ private static passRequest(action: string, data: any = {}): Promise { return new Promise((resolve, reject) => { const timer = setTimeout(() => reject({ code: 0, msg: '战令请求超时,请重试' }), 6000); Utils.POST('passCheckUpgrade', { uid: cc.fx.GameConfig.GM_INFO.uid || Utils.uid, action, ...data }, res => { clearTimeout(timer); res.code === 1 ? resolve(res) : reject(res); }); }); } private static passUpload(pass: any): any { const legacy = legacyPassInfo(pass, cc.fx.GameConfig.PASS_CHECK, cc.fx.GameConfig.PASS_CHECK_OLD); for (const key of [1, 2]) if (pass[key] && Number(pass[key].time)) pass[key].legacyExperience = legacyExperience(legacy[key]); return { passCheck: JSON.stringify(pass), legacy: JSON.stringify(legacy) }; } static addPassProgress() { Utils.getPassCheckInfo(res => { if (res.code !== 1 || !res.data.upgradeReady) return; cc.fx.GameConfig.GM_INFO.getItemType = 2; let pass = JSON.parse(res.data.passCheck); const end = Number(res.data.time) + PASS_PERIOD; if (!pass) pass = { 1: { time: '0', free: [], passCheck: [] } }; if (!pass[2] || Number(pass[2].time) <= Date.now()) { if (pass[2]) pass[1] = pass[2]; pass[2] = { time: String(end), experience: 0, free: [], passCheck: [], activate: false }; } const stage = normalizePass(pass[2], cc.fx.GameConfig.PASS_CHECK); const before = stage.unlocked; stage.experience += passTier(stage) === 30 ? 2 : 1; pass[2] = normalizePass(stage, cc.fx.GameConfig.PASS_CHECK); cc.fx.GameConfig.GM_INFO.getProgress = pass[2].progress; cc.fx.GameConfig.GM_INFO.getProgressLevel = pass[2].progressLevel; if (pass[2].unlocked > before) cc.fx.GameConfig.GM_INFO.popPassCheck = true; Utils.setPassCheckInfo(() => { }, pass); }); } static async completePassOrder(outTradeNo: string): Promise { for (let attempt = 0; attempt < 3; attempt++) { const order = await Utils.passRequest('order', { outTradeNo }); if (order.data.alreadyGranted) { Utils.applyPassGift(outTradeNo); return order; } const pass = mergePassInfo(JSON.parse(order.data.legacy || '{}'), order.data.extra, cc.fx.GameConfig.PASS_CHECK, cc.fx.GameConfig.PASS_CHECK_OLD); let key = [1, 2].find(k => String(pass[k] && pass[k].time) === order.data.passEnd); if (!key && order.data.extra[order.data.passEnd]) { key = 1; pass[1] = order.data.extra[order.data.passEnd]; } if (!key) throw { code: 410, msg: '订单所属期已过期,请联系客服' }; pass[key].activate = true; pass[key].tier = order.data.targetTier; if (order.data.bonus) pass[key].experience += 20; pass[key] = normalizePass(pass[key], key === 1 ? cc.fx.GameConfig.PASS_CHECK_OLD : cc.fx.GameConfig.PASS_CHECK); // 沿用客户端计算后上传,赠金仅通过战令接口随本期发奖记录一起保存。 const coinAmount = Math.floor(cc.fx.GameConfig.GM_INFO.coin) + (order.data.bonus ? 3000 : 0); const giftKey = (cc.fx.GameConfig.GM_INFO.uid || Utils.uid) + ':' + outTradeNo; if (order.data.bonus && Utils.passGiftPending[giftKey] !== 'applied') Utils.passGiftPending[giftKey] = 'pending'; try { const saved = await Utils.passRequest('save', { ...Utils.passUpload(pass), revision: order.data.revision, outTradeNo, coinAmount }); if (saved.data.bonus && !saved.data.alreadyGranted) { Utils.applyPassGift(outTradeNo); } return saved; } catch (error) { // 响应可能丢失,先确认战令收据;只补本次进程尚未发布的赠金。 const confirmed = await Utils.passRequest('order', { outTradeNo }); if (confirmed.data.alreadyGranted) { Utils.applyPassGift(outTradeNo); return { ...confirmed, data: { ...confirmed.data, bonus: order.data.bonus, alreadyGranted: false } }; } if (error.code !== 409 || attempt === 2) throw error; } } } //修改储存城市信息 static setCityInfo(callBack, data, useReverseGeocoding) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', address: data, } if (useReverseGeocoding == false || data == "" || data == "其他") { if (callBack) callBack(null); } else { console.log("设置城市信息数据:", setData); Utils.POST("address", setData, res => { if (res.code === 1) { console.log("设置城市信息成功", res); if (callBack) callBack(res); } else { console.log("设置城市信息失败", res); } }) } } } //设置城市信息失败 static setFailCityInfo() { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let locationInfo = { type: "coordinate", result: cc.fx.GameConfig.GM_INFO.address, is_success: false, info: cc.fx.GameConfig.GM_INFO.longitude } cc.fx.GameTool.shushu_Track("location", locationInfo); // let setData = { // uid: cc.fx.GameConfig.GM_INFO.uid, // action: 'save', // address: "其他", // } // Utils.POST("address", setData, res => { // if (res.code === 1) { // console.log("设置城市信息成功", res); // } else { // console.log("设置城市信息失败", res); // } // }) } } //获取城市前100名排名 static getCityRank(callBack, data) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let address = data; if (address == "" || address == null || address == undefined) { address = "其他"; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', address: address, } console.log("sos_______________s:", setData); let otherRank = null; let selfRank = null; Utils.POST("getAddressRankOther", setData, res => { if (res.code === 1) { otherRank = res.data || []; // console.log("五彩消消乐设置城市信息成功", res); Utils.POST("getAddressRankSelf", setData, res => { if (res.code === 1) { // console.log("消消王者设置城市信息成功", res); selfRank = res.data || []; // 合并两个数组 const mergeRank = (otherRank || []).concat(selfRank || []); // 按 addLevel 值降序排序(addLevel 越大排名越靠前) mergeRank.sort((a, b) => { return (b.addLevel || 0) - (a.addLevel || 0); }); res.data = mergeRank; if (callBack) callBack(res); } else { // console.log("1设置城市信息失败", res); } }) } else { // console.log("1设置城市信息失败", res); } }) } } static getShopDouble(callBack) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } console.log("获取双倍信息数据:", setData); Utils.POST("shopDouble", setData, res => { if (res.code === 1) { console.log("获取双倍信息成功", res); if (callBack) callBack(res); } else { console.log("获取双倍信息失败", res); } }) } } static setShopDouble(callBack, data) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', shopDouble: JSON.stringify(data), } Utils.POST("shopDouble", setData, res => { if (res.code === 1) { console.log("设置双倍信息成功", res); if (callBack) callBack(res); } else { console.log("设置双倍信息失败", res); } }) } } static setEndlessLevel(callBack, data1, data2) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', userLevel: parseInt(data1), // JSON.stringify(data1), // endLevelNum: parseInt(data2), } console.log("设置无尽关卡等级:", setData); Utils.POST("setUserLevel", setData, res => { if (res.code === 1) { let endLevelNum = res.data.endLevelNum; if (parseInt(data2) < Number(endLevelNum)) cc.fx.GameConfig.GM_INFO.endLevelNum = Number(endLevelNum); console.log("设置无尽关卡", res); if (callBack) callBack(res); } else { console.log("设置无尽关卡", res); } }) } } static getEndlessLevel(callBack) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("setUserLevel", setData, res => { console.log("获得无尽关卡等级:", res); if (res.code === 1) { if (callBack) callBack(res); } else { if (callBack) callBack(res); } }); } } static getRedeemInfo(callBack, cdk) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, cdk: cdk, } Utils.POST("redeem", setData, res => { if (res.code === 1) { if (callBack) callBack(res); } else { if (callBack) callBack(res); } }); } } static getUserInfoByID(callBack) { //@ts-ignore if ((typeof wx !== 'undefined' && wx !== null) || (typeof tt !== 'undefined' && tt !== null)) { let uid = cc.fx.GameConfig.GM_INFO.otherUid; //旧的读取数据设置数据方法,以强联网为主 let setData = { uid: uid } Utils.POST("getUserInfoByID", setData, res => { // //console.log("获得monthGetReward数据:", res); if (res.code === 1) { console.log("服务器:获得分享人头像昵称'✅ ", res); if (callBack) callBack(res); } else { console.log("服务器:获得分享人头像昵称'❌ ", res); if (callBack) callBack(res); } }); } } //获取 static getCommentInfo(callBack) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', } Utils.POST("comment", setData, res => { if (res.code === 1) { console.log("请求评论成功:", res); if (callBack) callBack(res); } else { console.log("请求评论失败:", res); if (callBack) callBack(res); } }); } } //设置评论 static setCommentInfo(callBack, data, _pos) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'save', pos: _pos, level: cc.fx.GameConfig.GM_INFO.level, comment: JSON.stringify(data), } console.log("设置评论数据:", setData); Utils.POST("comment", setData, res => { if (res.code === 1) { console.log("设置评论成功", res); if (callBack) callBack(res); } else { console.log("设置评论失败", res); } }) } } //获取点赞 static getLikeInfo(callBack, _pos) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'read', level: cc.fx.GameConfig.GM_INFO.level, pos: _pos, } Utils.POST("comment", setData, res => { if (res.code === 1) { console.log("请求点赞成功:", res); if (callBack) callBack(res); } else { console.log("请求点赞失败:", res); if (callBack) callBack(res); } }); } } //设置点赞 static setLikeInfo(callBack, _pos, _index) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: 'like', level: cc.fx.GameConfig.GM_INFO.level, pos: _pos, index: _index, // comment: JSON.stringify(data), } console.log("设置点赞数据:", setData); Utils.POST("comment", setData, res => { if (res.code === 1) { console.log("设置点赞成功", res); if (callBack) callBack(res); } else { console.log("设置点赞失败", res); } }) } } //#region 抽卡相关 /**抽卡*/ static getGacha‌(callBack) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, } Utils.POST("drawHead", setData, res => { if (res.code === 1) { console.log("正常获取到抽卡结果", res); } else { console.log("获取抽卡失败,失败原因", res); } // 失败也必须回调,否则抽卡页的 Loading 和防重复点击状态无法恢复。 if (callBack) callBack(res); }) } } /**抽卡*/ static getCat(callBack) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, } Utils.POST("drawCat", setData, res => { if (res.code === 1) { console.log("正常获取到抽猫猫结果", res); } else { console.log("获取抽猫猫失败,失败原因", res); } // 失败也必须回调,否则抽卡页的 Loading 和防重复点击状态无法恢复。 if (callBack) callBack(res); }) } } /*获取所有用户所得头像*/ static getAvatar(callBack) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, } Utils.POST("getHeadInfo", setData, res => { if (res.code === 1) { console.log("正常获取用户头像接口所得数据", res); if (callBack) callBack(res); } else { console.log("获取头像接口失败,失败原因", res); } }) } } static getAvatarWithRetry(callBack) { const maxRetries = 3; let retryCount = 0; let isCallBackCalled = false; console.log("获取头像接口________"); const makeRequest = () => { if (retryCount >= maxRetries) { if (!isCallBackCalled) { console.log("获取头像失败,已达到最大重试次数"); if (callBack) callBack({ code: 0, data: null, message: '轮询超时,达到最大重试次数' }); isCallBackCalled = true; } return; } const timeoutId = setTimeout(() => { console.log("上一次尝试失败,重新尝试"); retryCount++; console.log(`获取头像超时,第 ${retryCount} 次重新请求`); makeRequest(); }, 4000); let uid = cc.fx.StorageMessage.getStorage("uid"); if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, } console.log("开始调用获取头像接口"); Utils.POST("getHeadInfo", setData, res => { clearTimeout(timeoutId); if (!isCallBackCalled) { if (callBack) callBack(res); isCallBackCalled = true; } }); }; console.log("执行"); makeRequest(); } /*获取所有用户代币*/ static getFilm(callBack) { //@ts-ignore if (typeof wx !== 'undefined' && wx !== null) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, } Utils.POST("getFilm", setData, res => { if (res.code === 1) { console.log("正常获取用户代币", res); if (res.data && res.data.film !== undefined) { cc.fx.GameConfig.GM_INFO.film = Number(res.data.film); } if (callBack) callBack(res); } else { console.log("获取代币失败,失败原因", res); } }) } } static setForcedUpdate(callBack?) { let uid = cc.fx.StorageMessage.getStorage("uid"); //旧的读取数据设置数据方法,以强联网为主 if (uid != undefined && uid != "" && uid != null) { cc.fx.GameConfig.GM_INFO.uid = uid; } let setData = { uid: cc.fx.GameConfig.GM_INFO.uid, } Utils.POST("setForcedUpdate", setData, res => { if (res.code === 1) { console.log("设置强制更新成功", res); } else { console.log("设置强制更新失败", res); } if (callBack) callBack(res); }) } static wucaiTransfer( action: "claim_reward" | "choose_wucai" | "choose_current" | "ack_reward_popup", callBack?, ) { const isProgressChoice = action === "choose_wucai" || action === "choose_current"; const wasPendingChoice = Number(cc.fx.GameConfig.GM_INFO.wucai_type) === 1; const wucaiLevelAmount = cc.fx.GameConfig.GM_INFO.wucai_preview?.levelAmount; const xiaoxiaoLevelAmount = cc.fx.GameConfig.GM_INFO.wucai_current_preview?.levelAmount; const setData = { uid: cc.fx.GameConfig.GM_INFO.uid, action: action, }; Utils.POST("wucaiTransfer", setData, res => { if (res.code === 1 && action === "claim_reward") { const data = res.data || {}; const coinAmount = Number(data.coinAmount); const freezeAmount = Number(data.freezeAmount); const hammerAmount = Number(data.hammerAmount); const magicAmount = Number(data.magicAmount); if (!Number.isFinite(coinAmount) || !Number.isFinite(freezeAmount) || !Number.isFinite(hammerAmount) || !Number.isFinite(magicAmount)) { if (callBack) { callBack({ code: 0, errorCode: "WUCAI_REWARD_DATA_INVALID", msg: "奖励数据返回异常", }); } return; } const timestamp = Date.now(); 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("coin", { coin: coinAmount, timestamp }); cc.fx.StorageMessage.setStorage("prop", { freezeAmount, hammerAmount, magicAmount, timestamp, }); } if (res.code === 1 && res.data) { cc.fx.GameConfig.GM_INFO.wucai_type = Number(res.data.wucai_type); cc.fx.GameConfig.GM_INFO.wucai_reward_popup_pending = res.data.wucai_reward_popup_pending === true; } if (res.code === 1 && isProgressChoice && wasPendingChoice) { MiniGameSdk.API.shushu_TrackWucaiTransfer( 1, action === "choose_current" ? 1 : 0, wucaiLevelAmount, xiaoxiaoLevelAmount, ); MiniGameSdk.API.shushu_userSetTransferredFromWucai(true); } if (callBack) callBack(res); if (res.code === 1 && isProgressChoice) { MiniGameSdk.API.reboot(); } }); } }