662 lines
27 KiB
TypeScript
662 lines
27 KiB
TypeScript
import SevenDayGift from "./SevenDayGift";
|
||
import SevenDayGiftApi, { SevenDayActivityInfo, SevenDayApiTrace, SevenDayRewardItem } from "./SevenDayGiftApi";
|
||
import SevenDayGiftReward from "./SevenDayGiftReward";
|
||
import SevenDayGiftDebugPanel from "./debug/SevenDayGiftDebugPanel";
|
||
import SevenDayGiftApiFeedbackPanel from "./debug/SevenDayGiftApiFeedbackPanel";
|
||
import SevenDayHomeEntryLayout from "./SevenDayHomeEntryLayout";
|
||
|
||
const { ccclass, property } = cc._decorator;
|
||
const AUTO_OPEN_KEY = "seven_day_gift_auto_open_v1";
|
||
const DOOR_PREFAB_RESOURCE = "seven_day_gift/sevenDayGiftDoor";
|
||
|
||
@ccclass
|
||
export default class SevenDayGiftHost extends cc.Component {
|
||
@property(cc.Prefab)
|
||
giftPrefab: cc.Prefab = null;
|
||
|
||
@property(cc.Prefab)
|
||
doorPrefab: cc.Prefab = null;
|
||
|
||
private giftNode: cc.Node = null;
|
||
private giftView: SevenDayGift = null;
|
||
private doorNode: cc.Node = null;
|
||
private redDot: cc.Node = null;
|
||
private info: SevenDayActivityInfo = null;
|
||
private querying = false;
|
||
private retryCount = 0;
|
||
private debugPanel: SevenDayGiftDebugPanel = null;
|
||
private apiFeedbackPanel: SevenDayGiftApiFeedbackPanel = null;
|
||
private homeEntryLayout: SevenDayHomeEntryLayout = null;
|
||
private loadingSequence = 0;
|
||
private loadingTimer: any = null;
|
||
private loadingVisible = false;
|
||
private debugMode = "尚未执行";
|
||
private debugMessage = "等待活动初始化";
|
||
|
||
onLoad() {
|
||
if (!this.giftPrefab) {
|
||
cc.error("[SevenDayGiftHost] sevenDayGift prefab is not assigned");
|
||
return;
|
||
}
|
||
if (this.node.parent) this.node.setContentSize(this.node.parent.getContentSize());
|
||
|
||
this.giftNode = cc.instantiate(this.giftPrefab);
|
||
this.giftNode.active = false;
|
||
this.giftNode.setPosition(0, 0);
|
||
this.node.addChild(this.giftNode);
|
||
this.giftView = this.giftNode.getComponent(SevenDayGift);
|
||
|
||
this.setupDoor();
|
||
this.setupHomeEntryLayout();
|
||
this.setupDebugPanel();
|
||
cc.game.on(cc.game.EVENT_SHOW, this.onGameShow, this);
|
||
this.queryActivity(true);
|
||
}
|
||
|
||
onDestroy() {
|
||
cc.game.off(cc.game.EVENT_SHOW, this.onGameShow, this);
|
||
this.unschedule(this.refreshHomeEntryLayout);
|
||
this.closeHomeLoading(this.loadingSequence);
|
||
if (this.doorNode) this.doorNode.off(cc.Node.EventType.TOUCH_END, this.onDoorClicked, this);
|
||
if (this.debugPanel) this.debugPanel.destroy();
|
||
SevenDayGiftApi.setDebugTraceListener(null);
|
||
if (this.apiFeedbackPanel) this.apiFeedbackPanel.destroy();
|
||
}
|
||
|
||
private setupDoor() {
|
||
this.doorNode = cc.find("Canvas/Load/Top/sevenDayDoor");
|
||
if (!this.doorNode) {
|
||
cc.error("[SevenDayGiftHost] Canvas/Load/Top/sevenDayDoor is missing");
|
||
return;
|
||
}
|
||
let button = this.doorNode.getComponent(cc.Button);
|
||
if (!button) button = this.doorNode.addComponent(cc.Button);
|
||
button.transition = cc.Button.Transition.SCALE;
|
||
button.duration = 0.1;
|
||
button.zoomScale = 1.1;
|
||
this.doorNode.active = false;
|
||
this.doorNode.on(cc.Node.EventType.TOUCH_END, this.onDoorClicked, this);
|
||
|
||
if (this.doorPrefab) {
|
||
this.mountDoorContent(this.doorPrefab);
|
||
return;
|
||
}
|
||
|
||
// 兼容 Creator 编辑器新增序列化字段后,旧场景缓存暂时没有带上引用的情况。
|
||
cc.loader.loadRes(DOOR_PREFAB_RESOURCE, cc.Prefab, (error: Error, prefab: cc.Prefab) => {
|
||
if (!cc.isValid(this.node)) return;
|
||
if (error || !prefab) {
|
||
cc.error("[SevenDayGiftHost] sevenDayGiftDoor prefab load failed", error);
|
||
return;
|
||
}
|
||
this.doorPrefab = prefab;
|
||
this.mountDoorContent(prefab);
|
||
});
|
||
}
|
||
|
||
private mountDoorContent(prefab: cc.Prefab) {
|
||
if (!this.doorNode || !cc.isValid(this.doorNode)) return;
|
||
let content = this.doorNode.getChildByName("sevenDayGiftDoorContent");
|
||
if (!content) {
|
||
content = cc.instantiate(prefab);
|
||
content.setPosition(0, 0);
|
||
this.doorNode.addChild(content);
|
||
}
|
||
this.redDot = content.getChildByName("redDot");
|
||
this.refreshActivityState();
|
||
}
|
||
|
||
private queryActivity(allowAutoOpen: boolean, callback?: (success: boolean) => void, forceServer = false) {
|
||
if (CC_PREVIEW && !forceServer) {
|
||
this.showPreviewActivity(allowAutoOpen);
|
||
if (callback) callback(true);
|
||
return;
|
||
}
|
||
if (this.querying) {
|
||
this.setDebugMessage("查询仍在进行中,请勿重复点击");
|
||
if (callback) callback(false);
|
||
return;
|
||
}
|
||
if (!SevenDayGiftApi.getUid()) {
|
||
this.setDebugMessage("等待 uid,第 " + (this.retryCount + 1) + " 次检查");
|
||
if (this.retryCount < 10) {
|
||
this.retryCount++;
|
||
this.scheduleOnce(() => this.queryActivity(allowAutoOpen, callback, forceServer), 1);
|
||
} else {
|
||
this.setDebugMessage("查询失败:10 秒内没有取得 uid");
|
||
if (callback) callback(false);
|
||
}
|
||
return;
|
||
}
|
||
|
||
this.querying = true;
|
||
this.debugMode = "真实测试服";
|
||
this.setDebugMessage("正在请求 signInActivityInfo...");
|
||
SevenDayGiftApi.getInfo(response => {
|
||
this.querying = false;
|
||
this.setDebugMessage(this.formatDebugResponse(response));
|
||
if (!response || response.code !== 1 || !response.data) {
|
||
if (callback) callback(false);
|
||
return;
|
||
}
|
||
this.retryCount = 0;
|
||
this.info = response.data;
|
||
this.refreshActivityState();
|
||
if (this.giftView) this.giftView.setData(this.info, this.claimReward.bind(this));
|
||
if (allowAutoOpen && this.shouldAutoOpen()) {
|
||
this.markAutoOpened();
|
||
this.giftView.show();
|
||
}
|
||
if (callback) callback(true);
|
||
});
|
||
}
|
||
|
||
private refreshActivityState() {
|
||
const visible = this.isActivityVisible();
|
||
if (this.doorNode) this.doorNode.active = visible;
|
||
if (this.redDot) this.redDot.active = visible && !!this.info.canClaim;
|
||
if (!visible && this.giftNode) this.giftNode.active = false;
|
||
this.refreshHomeEntryLayout();
|
||
}
|
||
|
||
private setupHomeEntryLayout() {
|
||
const top = cc.find("Canvas/Load/Top");
|
||
if (!top) return;
|
||
this.homeEntryLayout = new SevenDayHomeEntryLayout(top);
|
||
this.refreshHomeEntryLayout();
|
||
this.schedule(this.refreshHomeEntryLayout, 0.25);
|
||
}
|
||
|
||
private refreshHomeEntryLayout() {
|
||
if (this.homeEntryLayout) this.homeEntryLayout.refresh();
|
||
}
|
||
|
||
private isActivityVisible(): boolean {
|
||
if (!this.info || !this.info.activityId || !this.info.triggerReached) return false;
|
||
if (this.info.status === "expired" || this.info.status === "completed") return false;
|
||
const serverNow = this.toTime(this.info.serverNow);
|
||
const endAt = this.toTime(this.info.endAt);
|
||
return !serverNow || !endAt || serverNow < endAt;
|
||
}
|
||
|
||
private shouldAutoOpen(): boolean {
|
||
if (!this.isActivityVisible() || !this.info.canClaim) return false;
|
||
return cc.fx.StorageMessage.getStorage(this.getAutoOpenStorageKey()) !== this.getServerDayKey();
|
||
}
|
||
|
||
private markAutoOpened() {
|
||
cc.fx.StorageMessage.setStorage(this.getAutoOpenStorageKey(), this.getServerDayKey());
|
||
}
|
||
|
||
private getAutoOpenStorageKey(): string {
|
||
return AUTO_OPEN_KEY + ":" + SevenDayGiftApi.getUid() + ":" + this.info.activityId;
|
||
}
|
||
|
||
private getServerDayKey(): string {
|
||
const time = this.toTime(this.info.serverNow) || Date.now();
|
||
return Math.floor((time + 8 * 60 * 60 * 1000) / (24 * 60 * 60 * 1000)).toString();
|
||
}
|
||
|
||
private onDoorClicked(event: cc.Event) {
|
||
event.stopPropagation();
|
||
const loadingToken = this.openHomeLoading(12000);
|
||
this.queryActivity(false, success => {
|
||
this.closeHomeLoading(loadingToken);
|
||
if (success && this.isActivityVisible()) this.giftView.show();
|
||
else if (this.info && this.isActivityVisible()) this.giftView.show();
|
||
});
|
||
}
|
||
|
||
private claimReward(callback: (success: boolean, message?: string) => void) {
|
||
const loadingToken = this.openHomeLoading(7000);
|
||
this.debugMode = "真实测试服";
|
||
this.setDebugMessage("正在请求 signInClaim(会修改测试服数据)...");
|
||
SevenDayGiftApi.claim(response => {
|
||
if (!response || response.code !== 1 || !response.data) {
|
||
this.closeHomeLoading(loadingToken);
|
||
this.setDebugMessage("领取接口失败:" + this.formatDebugResponse(response));
|
||
callback(false, response && response.msg ? response.msg : "领取失败,请稍后重试");
|
||
return;
|
||
}
|
||
this.setDebugMessage("领取接口成功,正在发放前端奖励:claimId=" + response.data.claimId
|
||
+ " rewardDay=" + response.data.rewardDay);
|
||
SevenDayGiftReward.grant(response.data, (success: boolean, message?: string) => {
|
||
if (!success) {
|
||
this.closeHomeLoading(loadingToken);
|
||
this.setDebugMessage("前端发奖失败:" + (message || "未知错误"));
|
||
callback(false, message);
|
||
return;
|
||
}
|
||
this.applyClaimState(response.data.rewardDay, response.data.claimedCount, response.data.completed);
|
||
this.closeHomeLoading(loadingToken);
|
||
this.showRewardWindow(response.data.rewards);
|
||
this.setDebugMessage("前端发奖完成,正在重新查询活动状态");
|
||
this.queryActivity(false, () => callback(true, "领取成功"));
|
||
});
|
||
});
|
||
}
|
||
|
||
private showPreviewActivity(open: boolean) {
|
||
if (!this.info) this.info = this.createPreviewInfo();
|
||
this.debugMode = "Cocos 预览模拟(不发奖)";
|
||
this.refreshActivityState();
|
||
if (this.giftView) this.giftView.setData(this.info, this.claimPreviewReward.bind(this));
|
||
if (open && this.giftView && this.shouldAutoOpen()) {
|
||
this.markAutoOpened();
|
||
this.giftView.show();
|
||
}
|
||
this.setDebugMessage("已加载编辑器预览数据");
|
||
}
|
||
|
||
private claimPreviewReward(callback: (success: boolean, message?: string) => void) {
|
||
const day = Number(this.info.nextRewardDay);
|
||
let previewRewards: SevenDayRewardItem[] = [];
|
||
this.info.rewards.forEach(reward => {
|
||
if (Number(reward.day) === day) {
|
||
reward.claimed = true;
|
||
previewRewards = reward.items || [];
|
||
}
|
||
});
|
||
this.info.claimedCount++;
|
||
this.info.todayClaimed = true;
|
||
this.info.canClaim = false;
|
||
if (this.info.claimedCount >= 7) this.info.status = "completed";
|
||
this.refreshActivityState();
|
||
this.giftView.setData(this.info, this.claimPreviewReward.bind(this));
|
||
this.showRewardWindow(previewRewards);
|
||
this.setDebugMessage("本地模拟领取完成:第 " + day + " 天(没有发放真实资产)");
|
||
callback(true, "预览领取成功(不会发放真实资产)");
|
||
}
|
||
|
||
private showRewardWindow(rewards: SevenDayRewardItem[]) {
|
||
if (!Array.isArray(rewards) || rewards.length === 0) return;
|
||
const displayRewards = rewards.map(item => {
|
||
const rewardCount = item.count !== undefined ? item.count : item.amount;
|
||
return {
|
||
type: item.type === "magic_wand" ? "magic" : item.type,
|
||
count: Math.max(0, Number(rewardCount) || 0),
|
||
spriteFrame: item.type === "cat_skin" && this.giftView ? this.giftView.catArt : null,
|
||
};
|
||
}).filter(item => item.count > 0);
|
||
if (displayRewards.length === 0) return;
|
||
|
||
const canvas = cc.find("Canvas");
|
||
const home: any = canvas && canvas.getComponent("JiaZai");
|
||
if (!home || typeof home.openRewardWindow !== "function") {
|
||
cc.warn("[SevenDayGift] 公共奖励弹窗不可用", displayRewards);
|
||
return;
|
||
}
|
||
home.openRewardWindow(displayRewards);
|
||
}
|
||
|
||
private createPreviewInfo(): SevenDayActivityInfo {
|
||
return {
|
||
serverNow: Date.now(),
|
||
activityId: "editor-preview",
|
||
status: "active",
|
||
triggerLevel: 23,
|
||
triggerReached: true,
|
||
startAt: Date.now(),
|
||
endAt: Date.now() + 14 * 24 * 60 * 60 * 1000,
|
||
claimedCount: 1,
|
||
todayClaimed: false,
|
||
canClaim: true,
|
||
nextRewardDay: 2,
|
||
rewards: [
|
||
{ day: 1, claimed: true, items: [{ type: "infinite_health", count: 900 }] },
|
||
{ day: 2, claimed: false, items: [{ type: "hammer", count: 1 }] },
|
||
{ day: 3, claimed: false, items: [{ type: "infinite_health", count: 1800 }] },
|
||
{ day: 4, claimed: false, items: [{ type: "freeze", count: 1 }, { type: "magic_wand", count: 1 }] },
|
||
{ day: 5, claimed: false, items: [{ type: "coin", count: 600 }] },
|
||
{ day: 6, claimed: false, items: [{ type: "hammer", count: 1 }, { type: "freeze", count: 1 }, { type: "magic_wand", count: 1 }] },
|
||
{ day: 7, claimed: false, items: [{ type: "infinite_health", count: 3600 }, { type: "cat_skin", count: 1, itemId: 12 }] },
|
||
],
|
||
};
|
||
}
|
||
|
||
private applyClaimState(rewardDay: number, claimedCount: number, completed: boolean) {
|
||
if (!this.info) return;
|
||
this.info.claimedCount = Number(claimedCount) || this.info.claimedCount;
|
||
this.info.todayClaimed = true;
|
||
this.info.canClaim = false;
|
||
if (completed) this.info.status = "completed";
|
||
if (Array.isArray(this.info.rewards)) {
|
||
this.info.rewards.forEach(reward => {
|
||
if (Number(reward.day) === Number(rewardDay)) reward.claimed = true;
|
||
});
|
||
}
|
||
this.refreshActivityState();
|
||
if (this.giftView) this.giftView.setData(this.info, this.claimReward.bind(this));
|
||
}
|
||
|
||
private onGameShow() {
|
||
this.queryActivity(true);
|
||
}
|
||
|
||
private setupDebugPanel() {
|
||
const environment = cc.fx.GameTool.getWechatGameVersion();
|
||
if (environment === "正式版") return;
|
||
if (!CC_PREVIEW && !CC_DEBUG && environment !== "开发版" && environment !== "体验版") return;
|
||
|
||
this.debugPanel = new SevenDayGiftDebugPanel(this.node, {
|
||
getStatusText: () => this.getDebugStatusText(),
|
||
queryServer: () => this.debugQueryServer(),
|
||
openGift: () => this.debugOpenGift(),
|
||
clearAutoOpen: () => this.debugClearAutoOpen(),
|
||
mockDay: (day: number) => this.debugMockDay(day),
|
||
mockTodayClaimed: () => this.debugMockTodayClaimed(),
|
||
mockCompleted: () => this.debugMockCompleted(),
|
||
mockExpired: () => this.debugMockExpired(),
|
||
addCoins: () => this.debugAddCoins(),
|
||
addHammer: () => this.debugAddProp("hammerAmount", "锤子"),
|
||
addFreeze: () => this.debugAddProp("freezeAmount", "冻结"),
|
||
addMagicWand: () => this.debugAddProp("magicAmount", "魔法棒"),
|
||
addInfiniteHealth: () => this.debugAddInfiniteHealth(),
|
||
});
|
||
this.debugPanel.build();
|
||
|
||
this.apiFeedbackPanel = new SevenDayGiftApiFeedbackPanel(this.node, {
|
||
queryAll: () => this.debugQueryAllApis(),
|
||
queryLevel: () => this.debugQueryLevel(),
|
||
queryActivity: () => this.debugQueryServer(),
|
||
queryCoin: () => this.debugQueryCoin(),
|
||
queryProps: () => this.debugQueryProps(),
|
||
queryPower: () => this.debugQueryPower(),
|
||
});
|
||
this.apiFeedbackPanel.build();
|
||
SevenDayGiftApi.setDebugTraceListener((trace: SevenDayApiTrace) => {
|
||
if (this.apiFeedbackPanel) this.apiFeedbackPanel.appendTrace(trace);
|
||
});
|
||
}
|
||
|
||
private openHomeLoading(timeoutMs: number): number {
|
||
const token = ++this.loadingSequence;
|
||
if (this.loadingTimer !== null) clearTimeout(this.loadingTimer);
|
||
|
||
const home = this.getHomeController();
|
||
if (home && typeof home.openLoad === "function") {
|
||
this.loadingVisible = true;
|
||
home.openLoad();
|
||
}
|
||
|
||
this.loadingTimer = setTimeout(() => this.closeHomeLoading(token), timeoutMs);
|
||
return token;
|
||
}
|
||
|
||
private closeHomeLoading(token: number) {
|
||
if (token !== this.loadingSequence) return;
|
||
if (this.loadingTimer !== null) {
|
||
clearTimeout(this.loadingTimer);
|
||
this.loadingTimer = null;
|
||
}
|
||
if (!this.loadingVisible) return;
|
||
|
||
this.loadingVisible = false;
|
||
const home = this.getHomeController();
|
||
if (home && typeof home.closeLoad === "function") home.closeLoad();
|
||
}
|
||
|
||
private getHomeController(): any {
|
||
const canvas = cc.find("Canvas");
|
||
return canvas && canvas.getComponent("JiaZai");
|
||
}
|
||
|
||
private getDebugStatusText(): string {
|
||
const environment = cc.fx.GameTool.getWechatGameVersion();
|
||
const level = Number(cc.fx.GameConfig.GM_INFO.level) || 0;
|
||
const lines = [
|
||
"模式:" + this.debugMode,
|
||
"环境:" + environment + " 服务器:" + SevenDayGiftApi.getServerUrl(),
|
||
"UID:" + (SevenDayGiftApi.getUid() || "未取得"),
|
||
"主线:已通过 " + level + " 关 / 当前第 " + (level + 1) + " 关",
|
||
"资产:金币 " + (Number(cc.fx.GameConfig.GM_INFO.coin) || 0)
|
||
+ " 锤子 " + (Number(cc.fx.GameConfig.GM_INFO.hammerAmount) || 0)
|
||
+ " 冻结 " + (Number(cc.fx.GameConfig.GM_INFO.freezeAmount) || 0)
|
||
+ " 魔法棒 " + (Number(cc.fx.GameConfig.GM_INFO.magicAmount) || 0),
|
||
];
|
||
if (this.info) {
|
||
lines.push("活动:" + (this.info.activityId || "无")
|
||
+ " status=" + this.info.status
|
||
+ " trigger=" + this.info.triggerReached);
|
||
lines.push("进度:" + this.info.claimedCount + "/7"
|
||
+ " next=" + this.info.nextRewardDay
|
||
+ " canClaim=" + this.info.canClaim
|
||
+ " todayClaimed=" + this.info.todayClaimed);
|
||
} else {
|
||
lines.push("活动:尚未取得有效数据");
|
||
}
|
||
lines.push("结果:" + this.debugMessage);
|
||
return lines.join("\n");
|
||
}
|
||
|
||
private setDebugMessage(message: string) {
|
||
this.debugMessage = new Date().toLocaleTimeString() + " " + message;
|
||
if (this.debugPanel) this.debugPanel.refresh();
|
||
}
|
||
|
||
private formatDebugResponse(response: any): string {
|
||
if (!response) return "接口没有返回数据";
|
||
const data = response.data || {};
|
||
return "code=" + response.code
|
||
+ " msg=" + (response.msg || "")
|
||
+ " activityId=" + (data.activityId || "")
|
||
+ " status=" + (data.status || "")
|
||
+ " triggerReached=" + data.triggerReached
|
||
+ " canClaim=" + data.canClaim;
|
||
}
|
||
|
||
private debugOpenGift() {
|
||
if (!this.info || !this.giftView) {
|
||
this.setDebugMessage("无法打开:当前没有活动数据,请先查询或选择模拟状态");
|
||
return;
|
||
}
|
||
this.giftView.show();
|
||
this.setDebugMessage("已执行打开活动弹窗");
|
||
}
|
||
|
||
private debugQueryServer() {
|
||
if (!this.canRunDebugServerQuery()) return;
|
||
if (this.debugMode.indexOf("模拟") >= 0) {
|
||
this.info = null;
|
||
this.refreshActivityState();
|
||
}
|
||
this.debugMode = "真实测试服";
|
||
this.queryActivity(false, undefined, true);
|
||
}
|
||
|
||
private debugQueryAllApis() {
|
||
if (!this.canRunDebugServerQuery()) return;
|
||
if (this.apiFeedbackPanel) {
|
||
this.apiFeedbackPanel.appendSystemMessage("开始查询活动、等级、金币、道具和无限体力。");
|
||
}
|
||
this.debugQueryServer();
|
||
this.debugQueryLevel();
|
||
this.debugQueryCoin();
|
||
this.debugQueryProps();
|
||
this.debugQueryPower();
|
||
}
|
||
|
||
private debugQueryLevel() {
|
||
if (!this.canRunDebugServerQuery()) return;
|
||
SevenDayGiftApi.getDebugLevel(response => {
|
||
const levelAmount = response && response.data ? response.data.levelAmount : undefined;
|
||
if (this.apiFeedbackPanel) {
|
||
this.apiFeedbackPanel.appendSystemMessage("服务器主线 levelAmount = "
|
||
+ (levelAmount === undefined ? "未返回" : levelAmount));
|
||
}
|
||
});
|
||
}
|
||
|
||
private debugQueryCoin() {
|
||
if (!this.canRunDebugServerQuery()) return;
|
||
SevenDayGiftApi.getDebugCoin(() => { });
|
||
}
|
||
|
||
private debugQueryProps() {
|
||
if (!this.canRunDebugServerQuery()) return;
|
||
SevenDayGiftApi.getDebugProps(() => { });
|
||
}
|
||
|
||
private debugQueryPower() {
|
||
if (!this.canRunDebugServerQuery()) return;
|
||
SevenDayGiftApi.getDebugPower(() => { });
|
||
}
|
||
|
||
private canRunDebugServerQuery(): boolean {
|
||
const environment = cc.fx.GameTool.getWechatGameVersion();
|
||
const allowed = environment === "开发版" || environment === "体验版";
|
||
if (!allowed) {
|
||
const message = "真实接口查询仅允许在微信开发版或体验版执行";
|
||
this.setDebugMessage(message);
|
||
if (this.apiFeedbackPanel) this.apiFeedbackPanel.appendSystemMessage(message);
|
||
}
|
||
return allowed;
|
||
}
|
||
|
||
private debugClearAutoOpen() {
|
||
if (!this.info || !this.info.activityId) {
|
||
this.setDebugMessage("无法清除:当前没有 activityId");
|
||
return;
|
||
}
|
||
cc.fx.StorageMessage.removeStorage(this.getAutoOpenStorageKey());
|
||
this.setDebugMessage("已清除今天的自动弹出记录,重新进入主页即可验证");
|
||
}
|
||
|
||
private debugMockDay(day: number) {
|
||
const info = this.createPreviewInfo();
|
||
info.activityId = "local-debug-day-" + day;
|
||
info.claimedCount = day - 1;
|
||
info.nextRewardDay = day;
|
||
info.todayClaimed = false;
|
||
info.canClaim = true;
|
||
info.rewards.forEach(reward => reward.claimed = reward.day < day);
|
||
this.applyDebugInfo(info, "本地模拟第 " + day + " 天,可点击奖励测试领取表现");
|
||
}
|
||
|
||
private debugMockTodayClaimed() {
|
||
const info = this.createPreviewInfo();
|
||
info.activityId = "local-debug-today-claimed";
|
||
info.claimedCount = 4;
|
||
info.nextRewardDay = 5;
|
||
info.todayClaimed = true;
|
||
info.canClaim = false;
|
||
info.rewards.forEach(reward => reward.claimed = reward.day <= 4);
|
||
this.applyDebugInfo(info, "本地模拟今天已领取:入口保留且不应自动弹出");
|
||
}
|
||
|
||
private debugMockCompleted() {
|
||
const info = this.createPreviewInfo();
|
||
info.activityId = "local-debug-completed";
|
||
info.status = "completed";
|
||
info.claimedCount = 7;
|
||
info.nextRewardDay = 7;
|
||
info.todayClaimed = true;
|
||
info.canClaim = false;
|
||
info.rewards.forEach(reward => reward.claimed = true);
|
||
this.applyDebugInfo(info, "本地模拟七天完成:主页入口应隐藏");
|
||
}
|
||
|
||
private debugMockExpired() {
|
||
const info = this.createPreviewInfo();
|
||
info.activityId = "local-debug-expired";
|
||
info.status = "expired";
|
||
info.serverNow = Date.now();
|
||
info.endAt = Date.now() - 1000;
|
||
info.canClaim = false;
|
||
this.applyDebugInfo(info, "本地模拟活动过期:主页入口应隐藏");
|
||
}
|
||
|
||
private debugAddCoins() {
|
||
const amount = 1000;
|
||
const coin = (Number(cc.fx.GameConfig.GM_INFO.coin) || 0) + amount;
|
||
cc.fx.GameConfig.GM_INFO.coin = coin;
|
||
cc.fx.StorageMessage.setStorage("coin", { coin, timestamp: Date.now() });
|
||
this.refreshHomeCoin();
|
||
|
||
if (!this.shouldSyncDebugAssets()) {
|
||
this.setDebugMessage("已在本地增加金币 " + amount + "(未请求服务器)");
|
||
return;
|
||
}
|
||
this.setDebugMessage("金币已增加,正在同步测试服 userCoin...");
|
||
SevenDayGiftApi.saveDebugCoin(coin, response => {
|
||
this.setDebugMessage("userCoin 同步完成:code=" + (response && response.code)
|
||
+ " msg=" + (response && response.msg || ""));
|
||
});
|
||
}
|
||
|
||
private debugAddProp(field: "hammerAmount" | "freezeAmount" | "magicAmount", label: string) {
|
||
const info: any = cc.fx.GameConfig.GM_INFO;
|
||
info[field] = (Number(info[field]) || 0) + 5;
|
||
const propData = {
|
||
freeze: Number(info.freezeAmount) || 0,
|
||
hammer: Number(info.hammerAmount) || 0,
|
||
magic_wand: Number(info.magicAmount) || 0,
|
||
};
|
||
cc.fx.StorageMessage.setStorage("prop", {
|
||
freezeAmount: propData.freeze,
|
||
hammerAmount: propData.hammer,
|
||
magicAmount: propData.magic_wand,
|
||
timestamp: Date.now(),
|
||
});
|
||
|
||
if (!this.shouldSyncDebugAssets()) {
|
||
this.setDebugMessage("已在本地增加" + label + " 5 个(未请求服务器)");
|
||
return;
|
||
}
|
||
this.setDebugMessage(label + "已增加,正在同步测试服 userProp...");
|
||
SevenDayGiftApi.saveDebugProps(propData, response => {
|
||
this.setDebugMessage("userProp 同步完成:code=" + (response && response.code)
|
||
+ " msg=" + (response && response.msg || ""));
|
||
});
|
||
}
|
||
|
||
private debugAddInfiniteHealth() {
|
||
const seconds = 15 * 60;
|
||
const now = Math.floor(Date.now() / 1000);
|
||
const oldEndAt = Number(cc.fx.StorageMessage.getStorage("userPowerTime")) || 0;
|
||
const endAt = Math.max(now, oldEndAt) + seconds;
|
||
cc.fx.GameConfig.GM_INFO.userPowerTime = endAt;
|
||
cc.fx.StorageMessage.setStorage("userPowerTime", endAt);
|
||
|
||
if (!this.shouldSyncDebugAssets()) {
|
||
this.setDebugMessage("已在本地增加无限体力 15 分钟(未请求服务器)");
|
||
return;
|
||
}
|
||
this.setDebugMessage("无限体力已增加,正在同步测试服 userPower...");
|
||
SevenDayGiftApi.saveDebugPower(endAt, response => {
|
||
this.setDebugMessage("userPower 同步完成:code=" + (response && response.code)
|
||
+ " msg=" + (response && response.msg || ""));
|
||
});
|
||
}
|
||
|
||
private shouldSyncDebugAssets(): boolean {
|
||
const environment = cc.fx.GameTool.getWechatGameVersion();
|
||
return environment === "开发版" || environment === "体验版";
|
||
}
|
||
|
||
private refreshHomeCoin() {
|
||
const canvas = cc.find("Canvas");
|
||
const home: any = canvas && canvas.getComponent("JiaZai");
|
||
if (home && home.updateCoin) home.updateCoin();
|
||
}
|
||
|
||
private applyDebugInfo(info: SevenDayActivityInfo, message: string) {
|
||
this.info = info;
|
||
this.debugMode = "本地模拟(不发奖)";
|
||
this.refreshActivityState();
|
||
if (this.giftView) {
|
||
this.giftView.setData(this.info, this.claimPreviewReward.bind(this));
|
||
this.giftView.show();
|
||
}
|
||
this.setDebugMessage(message);
|
||
}
|
||
|
||
private toTime(value: string | number): number {
|
||
if (typeof value === "number") return value < 100000000000 ? value * 1000 : value;
|
||
if (!value) return 0;
|
||
const parsed = new Date(value).getTime();
|
||
return isNaN(parsed) ? 0 : parsed;
|
||
}
|
||
|
||
}
|