import ch_util from "../ch_util"; /** * pvp扩展玩法 基于 chsdk */ export type pvp_player = { head: string, nickName: string, uid: number, hid: number, province: string, pvp: number, rank: number }; export type pvp_own_data = { extends: T, type: 0 | 1 | 2, time: number, own: pvp_player }; export type pvp_data = { extends: T, other: pvp_player, own: pvp_player, type?: 0 | 1 | 2, status?: 0 | 1 | 2, time?: number, reward?: number, pvpId?: string }; export type pvp_result = { other: { curRank: number, rank: number, curScore: number, score: number }, own: { curRank: number, rank: number, curScore: number, score: number } }; class ch_pvp { private readonly _set_url: string = '/user/setPvpSceneData'; private readonly _match_url: string = '/user/startPvpMatch'; private readonly _finish_url: string = '/user/pvpFinishAction'; private readonly _record_url: string = '/user/pvpChallengeRecord'; private static _instance: ch_pvp; public static getInstance(): ch_pvp { if (!this._instance) this._instance = new ch_pvp(); return this._instance; } /** * 设置自己的 PVP 擂台数据 * 该方法用于更新当前用户在 PVP 擂台上的数据。数据将根据传入的 extend 参数进行更新, * 并返回一个包含操作状态和可能错误信息的 Promise。 * @param extend - 一个pvp擂台数据对象,包含要更新的具体数据。 * @returns 一个 Promise,解析为一个包含以下属性的对象: * - code: 操作的结果状态。0 表示成功,其他值表示不同的错误类型。 * - err: 可选字符串,指示错误信息(如果有)。 */ public async setSceneData(extend: T): Promise<{ code: number, err?: string }> { const check = chsdk.check_req_time('setSceneData'); if (check) return check; const body = { extends: ch_util.stringify(extend) }; const ret = await chsdk.makePostTokenRequest(chsdk.getUrl(this._set_url), body); if (ret.code != chsdk.code.success) { chsdk.log.warn(ret); } else { chsdk.log.log(`PVP擂台数据上报成功`); if (!this._own) { await this.getOwn(); } else { this._own.extends = extend; } } return ret; } /** * 开始匹配 * @param uid (可选)具体好友的uid,默为空 * @returns null 匹配失败 * * pvp_data extends PVP 擂台数据 * other 台主信息 * own 自己的信息 * head:头像, nickName:名字, uid:id, hid:省id, province:省名, pvp:pvp排位分值, rank:pvp排行榜名次 */ public async startMatch(uid?: number | null): Promise | null> { const check = chsdk.check_req_time('startMatch'); if (check) return null; const ret = await chsdk.makePostTokenRequest(chsdk.getUrl(this._match_url), { uid: uid ? uid.toString() : '' }); if (ret.code != chsdk.code.success) { chsdk.log.warn(ret); return null; } else { const data = ret.data.data; data.other.uid = Number.parseInt(data.other.uid); data.other.hid = Number.parseInt(data.other.hid); data.other.province = chsdk.provinceCode2Name(data.other.hid); data.own.uid = Number.parseInt(data.own.uid); data.own.hid = Number.parseInt(data.own.hid); data.own.province = chsdk.provinceCode2Name(data.own.hid); return { extends: ch_util.parse(data.extends) as T, other: data.other, own: data.own } } } /**从一条记录开始匹配,用于复仇*/ public async startMatchRecord(pd: pvp_data): Promise | null> { const check = chsdk.check_req_time('startMatch'); if (check) return null; let pp = await this.startMatch(pd.other.uid); if (!pp) return null; pp.extends = pd.extends; pp.pvpId = pd.pvpId; return pp; } /** * 完成pvp上报 * @param otherUid 对方uid * @param status 0:挑战失败 1:挑战胜利 * @param ext PVP 擂台数据 * @param serverData 服务器处理排行数据,订阅消息 * ..ownValue 增减自己排位分值 * ..otherValue 增减对方排位分值 * ..msg 自定义的订阅消息 * @param pvpId 复仇id * @returns 对战结果 * other 对方的排名和分数变化 * own 自己的排名和分数变化 * curRank 当前排名(变动后) curScore 当前分数(变动后) rank 名数变动 score 分数变动 */ public async finish(otherUid: number, status: 0 | 1, ext: T, serverData: { ownValue?: number, otherValue?: number, msg?: string } , pvpId?: string ): Promise { const check = chsdk.check_req_time('finish'); if (check) return null; const body = { otherUid: otherUid.toString(), status: status, extends: ch_util.stringify(ext), serverData: ch_util.stringify(serverData), pvpId: pvpId }; const ret = await chsdk.makePostTokenRequest(chsdk.getUrl(this._finish_url), body); if (ret.code != chsdk.code.success) { chsdk.log.warn(ret); return null; } else { const data = ret.data.data; chsdk.log.log(`pvp结果数据上报成功,结算:`, data); return data; } } private _own: any; /**获取自己的pvp擂台数据*/ public async getOwn(): Promise | null> { if (!this._own) await this.getRecords(3, false); return this._own; } // private _cache_records: any | null = null; private _cache_time: number; private get_cache_records(): any | null { if (chsdk.date.now() - this._cache_time > 6e4) return null; return this._cache_records; } /** * 获取pvp对战记录 * @param type 0:全部纪录 1:被挑战的记录信息(默认) 2:挑战别人的记录 3:不需要纪录 * @param cache 默认为true,优先缓存拿数据,缓存存在一分钟 * @returns own:自己的PVP 擂台数据 * list:交互纪录 * extends PVP 擂台数据 * reward 奖励惩罚排位分值,由于serverData中得来 * type 0:自己的数据 1:被挑战的记录信息 2:挑战别人的记录 * status 0:挑战失败 1:挑战胜利 2:复仇成功 * time 时间 * pvpId pvp复仇id * other 对方信息 * own 自己信息 */ public async getRecords(typeId: 0 | 1 | 2 | 3 = 1, cache: boolean = true): Promise<{ own: pvp_own_data, list: pvp_data[], } > { if (cache) { const data = this.get_cache_records(); if (data) return data; } const check = chsdk.check_req_time('getRecords'); if (check) return null; const ret = await chsdk.makePostTokenRequest(chsdk.getUrl(this._record_url), { typeId: typeId }); if (ret.code != chsdk.code.success) { chsdk.log.warn(ret); return null; } else { let data = ret.data.data; if (data.own) { const d = data.own; d.extends = ch_util.parse(d.extends) as T; d.own.uid = Number.parseInt(d.own.uid); d.own.hid = Number.parseInt(d.own.hid); d.own.province = chsdk.provinceCode2Name(d.own.hid); } else { data.own = null; } data.list ||= []; for (let i = 0; i < data.list.length; i++) { const d = data.list[i]; d.extends = ch_util.parse(d.extends) as T; d.own.uid = Number.parseInt(d.own.uid); d.own.hid = Number.parseInt(d.own.hid); d.own.province = chsdk.provinceCode2Name(d.own.hid); d.other.uid = Number.parseInt(d.other.uid); d.other.hid = Number.parseInt(d.other.hid); d.other.province = chsdk.provinceCode2Name(d.other.hid); } this._own = data.own; this._cache_records = data; this._cache_time = chsdk.date.now(); return data; } } /** * 获取pvp排位分值榜单 * @returns */ public async getRank(): Promise<{ list: { head: string; nickName: string; rank: number; score: number; userId: number; [key: string]: any; }[], ower: { head: string; nickName: string; rank: number; score: number; userId: number; [key: string]: any; } }> { const d = await chsdk.loadRankData('pvp', 1, 100, true); return { list: d.data.list, ower: d.data.own }; } /** * 分享pvp数据,邀请对战 * @param player 玩家自己信息 * @param extend (可选)pvp关卡等数据 * @param title 分享显示标题 * @param imageUrl 分享显示图片 */ public async sharePvp(player: pvp_player, extend?: T, title?: string, imageUrl?: string) { chsdk.shareAppMessage(title, '', imageUrl, ch_util.stringify({ type: 'pvp', player: player, extends: extend })); } /** *获取从好友分享的pvp数据进入游戏的数据 */ public getSharePvpExtends(): { player: pvp_player, extend?: T } { const query = chsdk.getQuery(); if (!query) return null; const message = query.message; if (!message) return null; const data = ch_util.parse(message); if (!data) return null; if (data.type != 'pvp') return null; query.message = null; return { player: data.player, extend: data.extends as T }; } } // export default ch_pvp.getInstance();