import { NetBase, transUserDataform, transUserExtraDataform, UserData } from "./NetBase"; type EventNames> = Extract; type StartEventNames, Prefix extends string> = Extract extends infer K ? K extends `${Prefix}${string}` ? K : never : never; type EventParamFrist, Ev extends EventNames> = Ev extends keyof Map ? Map[Ev] extends (...args: infer Params) => any ? Params extends [infer First, ...any[]] ? First : never : never : never; type PickEvent = Pick>; type protocol = { extra?: Record } & chsdk.OmitIndex; /**网络玩家*/ export class NetPlayer extends NetBase { public readonly evt = chsdk.get_new_event>(); private _location: number = 0; private _online: boolean = true; private _ready: boolean = false; private _score: number = 0; /**总星数*/ public get score(): number { return this._score }; private _rank: number = 0; /**当局排名*/ public get rank(): number { return this._rank }; private _exit: boolean = false; /**是否退出游戏*/ private get isExit(): boolean { return this._exit }; private _totalRank: number = 0; /**总排名 */ public get totalRank(): number { return this._totalRank }; private _ishost: boolean = true; /**活跃可互动状态(在线,还没有离开房间,还没有结算名次)*/ public get active(): boolean { return this.online && !this.isExit && !this._rank }; /**房间位置0开头*/ public get location(): number { return this._location }; private _userData: UserData; /**游戏id*/ public get gid(): string { return this._userData.gid }; /**头像*/ public get head(): string { return this._userData.head }; /**省id*/ public get hid(): number { return this._userData.hid }; /**来自省份 */ public get province(): string { return this._userData.province }; public get ip(): string { return this._userData.ip }; /**最近登录时间戳*/ public get loginTime(): number { return this._userData.loginTime }; /**名称*/ public get nickName(): string { return this._userData.nickName }; /**平台d */ public get openId(): string { return this._userData.openId }; /**权限*/ public get option(): string { return this._userData.option }; /**平台*/ public get pf(): string { return this._userData.pf }; /**用户Id */ public get userId(): number { return this._userData.userId }; /**注册时间戳*/ public get registerTime(): number { return this._userData.registerTime }; /**是否是主机*/ public get isHost(): boolean { return this._ishost }; /**是否准备*/ public get ready(): boolean { return this._ready }; /**是否在线*/ public get online(): boolean { return this._online }; /**是否能开启匹配*/ public get canMatch(): boolean { return this.online && this.ready }; private _rankInfo: { LowerRank: number, Rank: number, Star: number } | null; private _userDataExtra: GD['extra'] = null; /**玩家扩展数据 */ public get userDataExtra(): GD['extra'] { return this._userDataExtra; }; /**获取玩家扩展数据某个字段*/ public getUserDataExtraField(key: K): GD['extra'][K] { return this._userDataExtra?.[key]; } /**段位信息*/ public get level(): { LowerRank: number, Rank: number, Star: number } | null { return this._rankInfo }; /**是否是当前玩家自己*/ private _isOwn: boolean = false; public get isOwn(): boolean { return this._isOwn }; /**是否是AI */ public get isAI(): boolean { return this._userData.userId < 8888; }; private _canAI: boolean = false; /**是否有控制当前AI权限*/ public get canAI(): boolean { return this._canAI; }; /**是否有此玩家数据权限*/ public get isPermission(): boolean { return this.isOwn || this._canAI; }; public init(pd: { location: number, status: boolean, userData: any, rank: number, TotalRank: number, score: number, teamReady?: boolean; gameData?: any, userRank?: any, userDataExtra?: any }): void { this._location = pd.location; this._online = pd.status ?? true; this._ready = pd.teamReady; this._score = pd.score; this._rank = pd.rank; this._totalRank = pd.TotalRank; this._userData = transUserDataform(pd.userData); this._rankInfo = pd.userRank; this._userDataExtra = transUserExtraDataform(pd.userDataExtra); if (pd.gameData) this.initValue(pd.gameData); } private set_userExtra(data: any): void { this._userDataExtra = data; (this.evt as any)._emit('p_extra'); } private set_level(level: { LowerRank: number, Rank: number, Star: number }, rank: number, score: number, totalRank: number): void { this._rankInfo = level; this._rank = rank; this._totalRank = totalRank; this._score = score; } private set_own(isOwn: boolean): void { this._isOwn = isOwn; } private set_host(isHost: boolean, ownHost: boolean): void { this._ishost = isHost; this._canAI = this.isAI && ownHost; } private change_online(ol: boolean): void { this._online = ol; (this.evt as any)._emit('online', this._online); } private change_ready(ready: boolean): void { this._ready = ready; (this.evt as any)._emit('ready', this._ready); } /**创建自定义obj数据*/ public creatObj(data: T): string { if (!this.isPermission) return; let oid: number = super.getValue('oid') ?? 0; oid++; const key = 'obj_' + oid; super.setValue('oid', oid); super.setValueDirty('oid', oid); super.setValue(key, data); super.setValueDirty(key, data); (this.evt as any)._emit('p_obj', key, data); return key; } /**根据key获取obj数据*/ public getObj(key: string): T { return super.getValue(key); } /**获取当前所有的obj数据*/ public getAllObj(): { key: string, data: T }[] { const list: { key: string, data: T }[] = []; const oid = super.getValue('oid') ?? 0; for (let i = 1; i <= oid; i++) { const key = 'obj_' + i; const data = super.getValue(key); if (data) list.push({ key: key, data: data === 0 ? null : data }); } return list; } /**不建议经常更改obj */ public changeObj(key: string, data: T): void { if (!this.isPermission) return; const old = super.getValue(key); if (old) { super.setValue(key, data); super.setValueDirty(key, data); (this.evt as any)._emit('p_obj', key, data, old); } } /**删除obj数据*/ public deleteObj(key: string) { if (!this.isPermission) return; const old = super.getValue(key); if (old) { super.setValue(key, 0); super.setValueDirty(key, 0); (this.evt as any)._emit('p_obj', key, null, old); } } /**修改某个键的值*/ public setValue, T2 extends EventParamFrist>(key: T, data: T2): void { if (!this.isPermission) return; let old = super.getValue(key); if (old) { if (typeof old === "object") { //old = JSON.parse(JSON.stringify(old)); } else if (data === old) { return; } } super.setValue(key, data); super.setValueDirty(key, data); (this.evt as any)._emit(key, data, old); } /**获取数据的值*/ public getValue, T2 extends EventParamFrist>(key: T): T2 { return super.getValue(key); } //服务器发送过来的数据 private server_change(data: { [key: string]: any }): void { if (this.isPermission) return; const evt: { evt: 0 | 1, key: string, data: any, old: any }[] = []; Object.keys(data).forEach(key => { const old = super.getValue(key); super.setValue(key, data[key]); if (key === 'oid') { return; } else if (key.startsWith('obj_')) { evt.push({ evt: 1, key: key, data: data[key] === 0 ? null : data[key], old: old }); } else { evt.push({ evt: 0, key: key, data: data[key], old: old }); } }); const e = (this.evt as any) for (let i = 0; i < evt.length; i++) { const ee = evt[i]; if (!ee) continue; if (ee.evt === 1) { e._emit('p_obj', ee.key, ee.data, ee.old); } else { e._emit(ee.key, ee.data, ee.old); } } } private setFinish(rank: number): void { this._rank = rank; (this.evt as any)._emit('finish', this._rank); } private exit(): void { this._exit = true; (this.evt as any)._emit('exit'); } private _finsh_tag: boolean = false; /**玩家完成游戏 不是自己或主机没有权限*/ public finishGame(): void { if (!this.isPermission) return; this._finsh_tag = true; } private doFinishGame(f: (id: string) => void): void { if (this._finsh_tag) f(this.Id); this._finsh_tag = false; } public dispose(): void { super.dispose(); this.evt.clearAll(); } }