import SevenDayGiftApi, { SevenDayRewardReceipt, SevenDayRewardItem } from "./SevenDayGiftApi"; const PROCESSED_CLAIMS_KEY = "seven_day_gift_processed_claims_v1"; /** 奖励到账与本地防重,只处理资产,不负责播放动画。 */ export default class SevenDayGiftReward { // 汇总奖励并同步资产,全部成功后才写入本地完成记录。 public static grant(result: SevenDayRewardReceipt, callback: (success: boolean, message?: string) => void) { if (!result || !result.claimId || !Array.isArray(result.rewards)) { callback(false, "服务器奖励数据不完整"); return; } if (this.hasProcessed(result.claimId)) { callback(true); return; } let coin = 0; let hammer = 0; let freeze = 0; let magic = 0; let infiniteHealth = 0; const cats: number[] = []; result.rewards.forEach((item: SevenDayRewardItem) => { const rewardAmount = item.count !== undefined ? item.count : item.amount; const amount = Math.max(0, Number(rewardAmount) || 0); switch (item.type) { case "coin": coin += amount; break; case "hammer": hammer += amount; break; case "freeze": freeze += amount; break; case "magic_wand": magic += amount; break; case "infinite_health": infiniteHealth += amount; break; case "cat_skin": if (item.itemId !== undefined) cats.push(Number(item.itemId)); break; } }); this.grantCommonRewards(coin, hammer, freeze, magic, infiniteHealth, (commonSuccess: boolean, commonMessage?: string) => { if (!commonSuccess) { callback(false, commonMessage); return; } this.saveCats(cats, 0, (success: boolean, message?: string) => { if (!success) { callback(false, message); return; } this.markProcessed(result.claimId); callback(true); }); }); } // 更新金币、道具和无限体力;有道具时同步服务端总量。 private static grantCommonRewards( coin: number, hammer: number, freeze: number, magic: number, infiniteHealth: number, callback: (success: boolean, message?: string) => void, ) { if (coin > 0) { cc.fx.GameTool.changeCoin(coin); } let propData = null; if (hammer > 0 || freeze > 0 || magic > 0) { const info = cc.fx.GameConfig.GM_INFO; info.hammerAmount = (Number(info.hammerAmount) || 0) + hammer; info.freezeAmount = (Number(info.freezeAmount) || 0) + freeze; info.magicAmount = (Number(info.magicAmount) || 0) + magic; propData = { freeze: info.freezeAmount, hammer: info.hammerAmount, magic_wand: info.magicAmount, }; cc.fx.StorageMessage.setStorage("prop", { hammerAmount: info.hammerAmount, freezeAmount: info.freezeAmount, magicAmount: info.magicAmount, timestamp: Date.now(), }); } if (infiniteHealth > 0) { // 服务端奖励值和体力接口都使用秒,原值传入,不做分钟换算。 cc.fx.GameTool.setUserPowerTime(infiniteHealth, "seven_day_gift"); } const canvas = cc.find("Canvas"); const home: any = canvas && canvas.getComponent("JiaZai"); if (home && home.updateCoin) { home.updateCoin(); } if (infiniteHealth > 0 && home && typeof home.updatePower === "function") { // 首次获得无限体力时也要切换主页显示并启动倒计时。 home.updatePower(); } if (!propData) { callback(true); return; } SevenDayGiftApi.saveProps(propData, response => { if (!response || response.code !== 1) { callback(false, response && response.msg ? response.msg : "道具同步失败"); return; } callback(true); }); } // 逐个保存猫皮肤,已保存也视为成功。 private static saveCats(cats: number[], index: number, callback: (success: boolean, message?: string) => void) { if (index >= cats.length) { callback(true); return; } const catNum = cats[index]; SevenDayGiftApi.saveCat(catNum, response => { const alreadySaved = response && response.msg === "已保存猫咪"; if (!response || (response.code !== 1 && !alreadySaved)) { callback(false, response && response.msg ? response.msg : "猫咪保存失败"); return; } const current = Array.isArray(cc.fx.GameConfig.GM_INFO.catArr) ? cc.fx.GameConfig.GM_INFO.catArr.slice() : []; if (current.indexOf(catNum) < 0) current.push(catNum); cc.fx.GameConfig.GM_INFO.catArr = response.data && Array.isArray(response.data.catArr) ? response.data.catArr : current; this.saveCats(cats, index + 1, callback); }); } // 检查本地是否已完成这次奖励同步。 private static hasProcessed(claimId: string): boolean { const records = cc.fx.StorageMessage.getStorage(PROCESSED_CLAIMS_KEY) || {}; return records[this.claimKey(claimId)] === true; } // 记录本次全部奖励已处理,供后续重复调用跳过。 private static markProcessed(claimId: string) { const records = cc.fx.StorageMessage.getStorage(PROCESSED_CLAIMS_KEY) || {}; records[this.claimKey(claimId)] = true; cc.fx.StorageMessage.setStorage(PROCESSED_CLAIMS_KEY, records); } // 同一个奖励记录按 UID 隔离,避免账号之间互相影响。 private static claimKey(claimId: string): string { return SevenDayGiftApi.getUid() + ":" + claimId; } }