Merge remote-tracking branch 'origin/main' into feature/seven_day_gift
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
/** 战令配置计算,不处理金币、登录或其他模块的同步。 */
|
||||
export const PASS_PERIOD = 30 * 24 * 60 * 60 * 1000;
|
||||
export const PASS_PRODUCTS = { battlepass: 1800, battlepass_30: 3000, battlepass_12: 1200 };
|
||||
const OLD_TOKENS = [1, 2, 2, 2, 2, 2, 2, 2, 2, ...Array(21).fill(4)];
|
||||
export function passTier(stage: any): number { return stage && stage.tier === 30 ? 30 : stage && stage.activate ? 18 : 0; }
|
||||
export function legacyExperience(stage: any): number {
|
||||
const level = Math.max(1, Math.min(30, Number(stage.progressLevel) || 1));
|
||||
return OLD_TOKENS.slice(0, level - 1).reduce((n, cost) => n + cost, 0) + Math.min(OLD_TOKENS[level - 1], Number(stage.progress) || 0);
|
||||
}
|
||||
export function normalizePass(stage: any, rows: any[]): any {
|
||||
if (!stage || !Number(stage.time)) return stage;
|
||||
stage = { ...stage, free: [...(stage.free || [])], passCheck: [...(stage.passCheck || [])] };
|
||||
if (!Number.isFinite(stage.experience)) {
|
||||
const level = Math.max(1, Math.min(30, Number(stage.progressLevel) || 1));
|
||||
stage.experience = rows.slice(0, level - 1).reduce((n, row) => n + Number(row.token), 0)
|
||||
+ Math.min(Number(rows[level - 1].token), Number(stage.progress) || 0);
|
||||
}
|
||||
let remaining = Math.max(0, stage.experience), unlocked = 0;
|
||||
for (const row of rows) {
|
||||
if (remaining < Number(row.token)) break;
|
||||
remaining -= Number(row.token);
|
||||
unlocked++;
|
||||
}
|
||||
stage.unlocked = unlocked;
|
||||
// 保持旧界面“当前档 + 当前档经验”的表示,完成一档时显示满格。
|
||||
const complete = remaining === 0 || unlocked === rows.length;
|
||||
stage.progressLevel = Math.max(1, Math.min(rows.length, unlocked + (complete ? 0 : 1)));
|
||||
stage.progress = complete ? Number(rows[stage.progressLevel - 1].token) : remaining;
|
||||
for (const lane of ['free', 'passCheck']) for (let i = 0; i < unlocked; i++) {
|
||||
if (stage[lane][i] !== 0) stage[lane][i] = 1;
|
||||
}
|
||||
return stage;
|
||||
}
|
||||
export function mergePassInfo(raw: any, extra: any, rows: any[], oldRows: any[] = rows): any {
|
||||
if (!raw) return raw;
|
||||
for (const key of [1, 2]) {
|
||||
const old = raw[key];
|
||||
if (!old || !Number(old.time)) continue;
|
||||
const saved = extra && extra[String(old.time)];
|
||||
if (saved) {
|
||||
raw[key] = { ...saved, activate: !!old.activate || !!saved.activate,
|
||||
experience: saved.experience + Math.max(0, legacyExperience(old) - (saved.legacyExperience || 0)) };
|
||||
for (const lane of ['free', 'passCheck']) {
|
||||
raw[key][lane] = [...(saved[lane] || [])];
|
||||
for (let i = 0; i < Math.min(30, (old[lane] || []).length); i++) if (old[lane][i] === 0) raw[key][lane][i] = 0;
|
||||
}
|
||||
}
|
||||
raw[key] = normalizePass(raw[key], key === 1 ? oldRows : rows);
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
export function legacyPassInfo(pass: any, rows: any[], oldRows: any[] = rows): any {
|
||||
const legacy: any = {};
|
||||
for (const key of [1, 2]) {
|
||||
const stage = pass[key];
|
||||
if (!stage || !Number(stage.time)) { legacy[key] = stage; continue; }
|
||||
const level = Math.max(1, Math.min(30, stage.progressLevel));
|
||||
const row = (key === 1 ? oldRows : rows)[stage.progressLevel - 1];
|
||||
const progress = stage.unlocked >= level ? OLD_TOKENS[level - 1] : Math.min(OLD_TOKENS[level - 1], Math.floor(stage.progress * OLD_TOKENS[level - 1] / Math.max(1, Number(row.token))));
|
||||
legacy[key] = { time: stage.time, activate: passTier(stage) > 0, progressLevel: level, progress,
|
||||
free: (stage.free || []).slice(0, 30), passCheck: (stage.passCheck || []).slice(0, 30) };
|
||||
}
|
||||
return legacy;
|
||||
}
|
||||
export function passBounds(stage: any, count: number) {
|
||||
const tier = passTier(stage);
|
||||
const generated = Math.min(count, tier === 30 ? Math.max(40, (stage.unlocked || 0) + 5) : 40);
|
||||
// 正常滚动至可解锁范围的下一档,后续奖励供上拉预览。
|
||||
const content = Math.min(generated, tier === 30 ? Math.max(36, (stage.unlocked || 0) + 1) : 36);
|
||||
return { generated, content };
|
||||
}
|
||||
export function canClaimPass(stage: any, index: number, left: boolean): boolean {
|
||||
return !!stage && index >= 0 && index < stage.unlocked && (stage[left ? 'free' : 'passCheck'] || [])[index] === 1
|
||||
&& (index < 35 ? left || passTier(stage) >= 18 : passTier(stage) === 30);
|
||||
}
|
||||
export function hasPassReward(stage: any): boolean {
|
||||
return !!stage && (stage.free || []).some((_, i) => canClaimPass(stage, i, true) || canClaimPass(stage, i, false));
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "b0d9322f-2367-43e0-9be4-9dbe97a65c79",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
||||
@@ -64,6 +64,7 @@ export class GameConfig {
|
||||
static NEW_LEVEL: any;
|
||||
static NEW_GUIDE: any;
|
||||
static PASS_CHECK: any;
|
||||
static PASS_CHECK_OLD: any;
|
||||
static PASS_RATE: any;
|
||||
static MESSAGE_MODEL: any;
|
||||
static LOCAL_CACHE_PREFIX = "level_cache_";
|
||||
@@ -662,7 +663,7 @@ export class GameConfig {
|
||||
vibrateOpen: true, //震动
|
||||
coinnum: 0, //每局的金币数
|
||||
paid_user: false, //是否是付费用户
|
||||
version: "1.0.50", //版本号
|
||||
version: "1.0.51", //版本号
|
||||
shushu_DistinctId: "", //数数访客ID
|
||||
shushu_AccountId: "", //数数账号ID
|
||||
uid: "", //用户和后端唯一id
|
||||
@@ -757,7 +758,14 @@ export class GameConfig {
|
||||
return;
|
||||
}
|
||||
const newLevelData = res.json;
|
||||
this.PASS_CHECK = newLevelData.Sheet1;
|
||||
cc.resources.load("Json/PASS_CHECK_OLD", (oldError: any, oldRes: cc.JsonAsset) => {
|
||||
if (oldError) {
|
||||
console.error("加载 PASS_CHECK_OLD.JSON 失败:", oldError);
|
||||
return;
|
||||
}
|
||||
this.PASS_CHECK_OLD = oldRes.json.Sheet1;
|
||||
this.PASS_CHECK = newLevelData.Sheet1;
|
||||
});
|
||||
// 可以根据需求对 newLevelData 进行处理
|
||||
// //console.log("PASS_CHECK.JSON 加载成功:", newLevelData);
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { MiniGameSdk } from "../../Sdk/MiniGameSdk";
|
||||
import { normalizePass, mergePassInfo, legacyPassInfo, legacyExperience, passTier, PASS_PERIOD } from '../Config/BattlePassModel';
|
||||
//#region 测试
|
||||
/** 测试 */
|
||||
export default class Utils {
|
||||
@@ -41,6 +42,7 @@ export default class Utils {
|
||||
isDebug: isDebug,
|
||||
distinctId: cc.fx.GameConfig.GM_INFO.shushu_DistinctId,
|
||||
wucai_capability: 1,
|
||||
passVersion: 2,
|
||||
};
|
||||
if (from === "wucai") {
|
||||
loginData.from = from;
|
||||
@@ -92,15 +94,19 @@ export default class Utils {
|
||||
|
||||
//#region 道具直购接口
|
||||
/**道具直购接口*/
|
||||
static buyProp(id, count, price, systemType, productId, callBack) {
|
||||
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 }, res => {
|
||||
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,
|
||||
@@ -125,7 +131,7 @@ export default class Utils {
|
||||
success(res, errCode) {
|
||||
// clearTimeout(timeoutId); // 清除超时定时器
|
||||
//console.log('成功', res, errCode);
|
||||
callBack(res);
|
||||
callBack(passEnd ? { ...res, outTradeNo: passOrder } : res);
|
||||
},
|
||||
fail({ errMsg, errCode }) {
|
||||
// clearTimeout(timeoutId); // 清除超时定时器
|
||||
@@ -139,14 +145,14 @@ export default class Utils {
|
||||
callBack(data);
|
||||
}
|
||||
})
|
||||
}
|
||||
} else if (passEnd) callBack({ err: res.msg || '战令下单失败' });
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//#region 安卓获取支付结果
|
||||
/** 安卓获取支付结果 */
|
||||
static getPayInfo(callBack) {
|
||||
static getPayInfo(callBack, passOrder?: string) {
|
||||
// 延迟时间数组,按照 1 秒 3 次、2 秒 5 次、5 秒 6 次、15 秒 5 次的规则生成
|
||||
const delays = [
|
||||
...Array(3).fill(3000),
|
||||
@@ -165,7 +171,7 @@ export default class Utils {
|
||||
|
||||
//console.log("请求uid:", Utils.uid);
|
||||
//console.log("outTradeNo:", Utils.outTradeNo);
|
||||
Utils.POST("wx/getPayInfo", { uid: Utils.uid, outTradeNo: Utils.outTradeNo }, res => {
|
||||
Utils.POST("wx/getPayInfo", { uid: Utils.uid, outTradeNo: passOrder || Utils.outTradeNo }, res => {
|
||||
//console.log("查询字符结果:", res);
|
||||
if (res.code === 1 && (res.data.pay_state === 1 || res.data.pay_state === 2)) {
|
||||
callBack(res);
|
||||
@@ -231,7 +237,7 @@ export default class Utils {
|
||||
cc.fx.GameConfig.GM_INFO.iosStarterOrder = null;
|
||||
cc.fx.GameConfig.GM_INFO.iosStarterOrder = order;
|
||||
}
|
||||
else if (iosPayInfo.payment_name == "battlepass") {
|
||||
else if (/^battlepass(?:_30|_12)?$/.test(iosPayInfo.payment_name)) {
|
||||
cc.fx.GameConfig.GM_INFO.iosPassCheckOrder = null;
|
||||
cc.fx.GameConfig.GM_INFO.iosPassCheckOrder = order;
|
||||
}
|
||||
@@ -249,6 +255,7 @@ export default class Utils {
|
||||
propName: iosPayInfo.payment_name,
|
||||
count: iosPayInfo.payment_count,
|
||||
price: iosPayInfo.price,//价格单位是分
|
||||
...(iosPayInfo.passEnd ? { passEnd: iosPayInfo.passEnd, passVersion: 2 } : {}),
|
||||
}
|
||||
const shushu_data = {
|
||||
outTradeNo: order,
|
||||
@@ -1356,54 +1363,129 @@ export default class Utils {
|
||||
}
|
||||
|
||||
//获取通行证信息
|
||||
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) {
|
||||
//@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("passCheck", setData, res => {
|
||||
console.log("获得通行证成功:", res);
|
||||
if (res.code === 1) {
|
||||
|
||||
if (callBack) callBack(res);
|
||||
} else {
|
||||
|
||||
if (callBack) callBack(res);
|
||||
}
|
||||
});
|
||||
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) {
|
||||
//@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',
|
||||
passCheck: JSON.stringify(data),
|
||||
}
|
||||
Utils.POST("passCheck", setData, res => {
|
||||
if (res.code === 1) {
|
||||
// console.log("请求通行证上传成功", res);
|
||||
if (callBack) callBack(res);
|
||||
} else {
|
||||
console.log("请求通行证上传失败", res);
|
||||
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<any> {
|
||||
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<any> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2680,6 +2680,9 @@ var GameTool = {
|
||||
},
|
||||
|
||||
handleMemoryWarning(res?: any) {
|
||||
// 仅 iOS 低内存机型响应告警,其他机型不进入降级和资源清理流程。
|
||||
if (!this.isLowMemoryIOSDevice()) return;
|
||||
|
||||
const firstWarning = !this._lowMemoryMode;
|
||||
this._lowMemoryMode = true;
|
||||
this._memoryWarningCount++;
|
||||
|
||||
Reference in New Issue
Block a user