MatchMaster/assets/seven_day_gift/SevenDayGiftApi.ts
2026-09-04 18:36:07 +08:00

237 lines
7.7 KiB
TypeScript

import Utils from "../Script/module/Pay/Utils";
export interface SevenDayRewardItem {
type: "coin" | "hammer" | "freeze" | "magic_wand" | "infinite_health" | "cat_skin";
amount?: number;
count?: number;
itemId?: number;
}
export interface SevenDayReward {
day: number;
items: SevenDayRewardItem[];
claimed: boolean;
}
export interface SevenDayActivityInfo {
serverNow: string | number;
activityId: string;
status: string;
triggerLevel: number;
triggerReached: boolean;
startAt: string | number;
endAt: string | number;
claimedCount: number;
todayClaimed: boolean;
canClaim: boolean;
nextRewardDay: number;
rewards: SevenDayReward[];
}
export interface SevenDayClaimResult {
claimId: string;
rewardDay: number;
rewards: SevenDayRewardItem[];
claimedCount: number;
todayClaimed: boolean;
completed: boolean;
}
export interface SevenDayResponse<T> {
code: number;
data: T;
msg?: string;
}
export interface SevenDayApiTrace {
requestId: number;
phase: "REQUEST" | "RESPONSE" | "TIMEOUT";
time: string;
endpoint: string;
url: string;
elapsedMs?: number;
payload: string;
}
export default class SevenDayGiftApi {
private static requestSequence = 0;
private static traceListener: (trace: SevenDayApiTrace) => void = null;
public static getInfo(callback: (response: SevenDayResponse<SevenDayActivityInfo>) => void) {
this.post("signInActivityInfo", { uid: this.getUid() }, callback);
}
public static claim(callback: (response: SevenDayResponse<SevenDayClaimResult>) => void) {
this.post("signInClaim", { uid: this.getUid() }, callback);
}
public static saveCat(catNum: number, callback: (response: SevenDayResponse<{ catArr: number[] }>) => void) {
this.post("setCatArr", {
uid: this.getUid(),
action: "save",
catNum,
}, callback);
}
public static saveDebugCoin(coinAmount: number, callback: (response: SevenDayResponse<any>) => void) {
this.post("userCoin", {
uid: this.getUid(),
action: "save",
coinAmount: Math.floor(coinAmount),
}, callback);
}
public static saveDebugProps(propData: object, callback: (response: SevenDayResponse<any>) => void) {
this.post("userProp", {
uid: this.getUid(),
action: "save",
propType: 0,
propData: JSON.stringify(propData),
}, callback);
}
public static saveDebugPower(userPowerTime: number, callback: (response: SevenDayResponse<any>) => void) {
this.post("userPower", {
uid: this.getUid(),
action: "save",
userPowerTime,
}, callback);
}
public static getDebugLevel(callback: (response: SevenDayResponse<any>) => void) {
this.post("userLevel", { uid: this.getUid(), action: "read" }, callback);
}
public static getDebugCoin(callback: (response: SevenDayResponse<any>) => void) {
this.post("userCoin", { uid: this.getUid(), action: "read" }, callback);
}
public static getDebugProps(callback: (response: SevenDayResponse<any>) => void) {
this.post("userProp", { uid: this.getUid(), action: "read" }, callback);
}
public static getDebugPower(callback: (response: SevenDayResponse<any>) => void) {
this.post("userPower", { uid: this.getUid(), action: "read" }, callback);
}
public static setDebugTraceListener(listener: (trace: SevenDayApiTrace) => void) {
this.traceListener = listener;
}
public static getUid(): string {
const storedUid = cc.fx.StorageMessage.getStorage("uid");
if (storedUid !== undefined && storedUid !== null && storedUid !== "") {
cc.fx.GameConfig.GM_INFO.uid = storedUid;
}
return cc.fx.GameConfig.GM_INFO.uid || "";
}
private static post<T>(endpoint: string, params: object, callback: (response: SevenDayResponse<T>) => void) {
const requestId = ++this.requestSequence;
const startedAt = Date.now();
const shouldLog = this.shouldDebugLog();
const url = this.getServerUrl() + endpoint;
let timeoutHandle: any = null;
let completed = false;
if (shouldLog) {
cc.log("[SevenDayGiftApi][#" + requestId + "][REQUEST]", {
time: new Date(startedAt).toISOString(),
endpoint,
url,
params: this.stringify(params),
});
this.emitTrace({
requestId,
phase: "REQUEST",
time: new Date(startedAt).toISOString(),
endpoint,
url,
payload: this.stringify(params, true),
});
}
timeoutHandle = setTimeout(() => {
if (completed) return;
completed = true;
const timeoutResponse: SevenDayResponse<T> = {
code: 0,
data: null,
msg: "请求超时,请稍后重试",
};
if (shouldLog) {
cc.warn("[SevenDayGiftApi][#" + requestId + "][TIMEOUT]", {
endpoint,
url,
elapsedMs: Date.now() - startedAt,
});
this.emitTrace({
requestId,
phase: "TIMEOUT",
time: new Date().toISOString(),
endpoint,
url,
elapsedMs: Date.now() - startedAt,
payload: "超过 5.5 秒未收到回调",
});
}
callback(timeoutResponse);
}, 5500);
Utils.POST(endpoint, params, response => {
if (completed) return;
completed = true;
if (timeoutHandle !== null) clearTimeout(timeoutHandle);
if (shouldLog) {
const responseLog = {
time: new Date().toISOString(),
endpoint,
url,
elapsedMs: Date.now() - startedAt,
response: this.stringify(response),
};
if (response && response.code === 1) {
cc.log("[SevenDayGiftApi][#" + requestId + "][RESPONSE]", responseLog);
} else {
cc.warn("[SevenDayGiftApi][#" + requestId + "][RESPONSE]", responseLog);
}
this.emitTrace({
requestId,
phase: "RESPONSE",
time: new Date().toISOString(),
endpoint,
url,
elapsedMs: Date.now() - startedAt,
payload: this.stringify(response, true),
});
}
callback(response);
});
}
public static getServerUrl(): string {
const environment = cc.fx.GameTool.getWechatGameVersion();
return environment === "开发版" || environment === "体验版"
? Utils.testHttpip
: Utils.httpip;
}
private static shouldDebugLog(): boolean {
const environment = cc.fx.GameTool.getWechatGameVersion();
if (environment === "正式版") return false;
return CC_PREVIEW || CC_DEBUG || environment === "开发版" || environment === "体验版";
}
private static emitTrace(trace: SevenDayApiTrace) {
if (this.traceListener) this.traceListener(trace);
}
private static stringify(value: any, pretty = false): string {
try {
return JSON.stringify(value, null, pretty ? 2 : 0);
} catch (error) {
return "[无法序列化] " + error;
}
}
}