159 lines
6.2 KiB
TypeScript
159 lines
6.2 KiB
TypeScript
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;
|
|
}
|
|
}
|