import { NetPlayer } from "./NetPlayer"; type PickEvent = Pick>; const C2S_MATCH = 'c2s_match'; const C2S_MATCH_CANCEL = 'c2s_match_cancel'; const C2S_READY = 'c2s_ready'; const C2S_KICK_OUT = 'c2s_kick_out'; /**网络队伍*/ export class NetTeam { /**队伍事件*/ public readonly evt = chsdk.get_new_event>(); private _status: boolean = true; /**队伍是否能进*/public get status(): boolean { return this._status }; private _hostId: string; /**队伍队长ID*/public get HostId(): string { return this._hostId }; private _password: string; /**队伍进入口令*/public get Password(): string { return this._password }; private _limit: number; /**队伍上限*/public get Limit(): number { return this._limit }; private _id: string; /**队伍标识id*/public get Id(): string { return this._id }; private _inCollect: boolean = false; /**是否在匹配中*/public get inCollect(): boolean { return this._inCollect }; private _own_id: string; private _players: Map> = new Map(); private _send: (type: string, data?: any) => void; constructor(data: any, send: (type: string, data?: any) => void) { const team = data.teamData; const playerData = data.playerData; this._hostId = team.hostInfo; this._status = team.status; this._inCollect = team.inCollect; this._password = team.password; this._limit = team.limit; this._id = team.roomId; this._players.clear(); let ps = Object.keys(playerData).map(key => ({ key, data: playerData[key] })); for (let i = 0; i < ps.length; i++) this.addPlayer(ps[i]); this._send = send; } /**主机开始匹配*/ public match(): void { if (!this.isHost) return; this._send(C2S_MATCH); } /**主机退出匹配*/ public exit_match(): void { if (!this.isHost) return; this._send(C2S_MATCH_CANCEL); } /**主机踢出某个玩家出小队 */ public kick_out(location: number): void; public kick_out(id: string): void; public kick_out(arg: string | number): void { if (!this.isHost) return; if (typeof arg === 'string') { this._send(C2S_KICK_OUT, arg); } else if (typeof arg === 'number') { const playerToKick = this.all.find(player => player.location === arg); if (playerToKick) this._send(C2S_KICK_OUT, playerToKick.Id); // 踢出找到的玩家 } } /**主机踢出所有没有准备的玩家 */ public kick_out_no_readys(): void { if (!this.isHost) return; const list = this.notreadys; for (let i = 0; i < list.length; i++) this._send(C2S_KICK_OUT, list[i].Id); } /**主机踢出所有不在线玩家*/ public kick_out_outlines(): void { if (!this.isHost) return; const list = this.outlines; for (let i = 0; i < list.length; i++) this._send(C2S_KICK_OUT, list[i].Id); } /**主机踢出所有不在线或没有准备的玩家*/ public kick_out_badplayers(): void { if (!this.isHost) return; const list = this.badplayers; for (let i = 0; i < list.length; i++) this._send(C2S_KICK_OUT, list[i].Id); } /**准备*/ public ready(): void { this._send(C2S_READY); } private addPlayer(p: any, isevt: boolean = false): void { const id = p.key; const pd = p.data; let player = this._players.get(id); if (!player) { player = new NetPlayer(id); this._players.set(id, player); } player.init(pd); (player as any).set_host(player.Id === this._hostId); if (player.isOwn) this._own_id = id; if (isevt) (this.evt as any)._emit('t_entry', id, player.location, player.nickName); } /**玩家离开*/ private removePlayer(id: string): void { const p = this._players.get(id) if (p) { const location = p.location; const nickName = p.nickName; this._players.delete(id); (this.evt as any)._emit('t_exit', id, location, nickName); } } /**队伍解散*/ private closed(): void { (this.evt as any)._emit('t_closed'); } private updatePlayerStatus(id: string, online: boolean): void { const p = this.getPlayer(id); if (p) { (p as any).change_online(online); const location = p.location; const nickName = p.nickName; (this.evt as any)._emit('t_online', id, online, location, nickName); } } private updatePlayerReady(id: string, ready: boolean): void { const p = this.getPlayer(id); if (p) { (p as any).change_ready(ready); const location = p.location; const nickName = p.nickName; (this.evt as any)._emit('t_ready', id, ready, location, nickName); } } private match_start(): void { this._inCollect = true; (this.evt as any)._emit('t_matchStart'); } private match_cancel(): void { this._inCollect = false; (this.evt as any)._emit('t_matchCancel'); } private match_success(): void { this._inCollect = false; (this.evt as any)._emit('t_matchSuccess'); const ps = this.getAllPlayer(); for (let i = 0; i < ps.length; i++) { (ps[i] as any).change_ready(false); } } private not_ready(): void { (this.evt as any)._emit('t_no_ready'); } private changeHost(id: string): void { this._hostId = id; this._players.forEach((v, _) => { (v as any).set_host(v.Id === this._hostId); }); const p = this.getPlayer(this._hostId); (this.evt as any)._emit('t_host', id, p.location, p.nickName); } private _chat_msg: string | null = null; private _last_chat_time: number = 0; /*队伍里聊天,成功返回true,发送频率过快返回false*/ public chat(msg: string): boolean { const now = chsdk.date.now(); if (now - this._last_chat_time < 1000) return false; this._last_chat_time = now; this._chat_msg = msg; return true; } private onChat(id: string, msg: string): void { const p = this.getPlayer(id); (this.evt as any)._emit('t_chat', id, msg, p.location, p.nickName); } private doSendChat(f: (msg: string) => void) { f(this._chat_msg); this._chat_msg = null; } /**自己是否是主机*/ get isHost(): boolean { return this._own_id === this._hostId; } /**自己的所有信息*/ public get own(): NetPlayer { return this._players.get(this._own_id); } /**所有玩家*/ public get all(): NetPlayer[] { return Array.from(this._players.values()); } /**其它玩家信息*/ public get others(): NetPlayer[] { return Array.from(this._players.values()).filter(player => !player.isOwn);; } /**在线玩家信息*/ public get onlines(): NetPlayer[] { return Array.from(this._players.values()).filter(player => player.online);; } /**不在线玩家信息*/ public get outlines(): NetPlayer[] { return Array.from(this._players.values()).filter(player => !player.online);; } /**没有准备或不在线玩家*/ public get badplayers(): NetPlayer[] { return Array.from(this._players.values()).filter(player => !player.ready || !player.online);; } /**准备好的玩家信息*/ public get readys(): NetPlayer[] { return Array.from(this._players.values()).filter(player => player.ready);; } /**没有准备的玩家信息*/ public get notreadys(): NetPlayer[] { return Array.from(this._players.values()).filter(player => !player.ready);; } /**某个玩家的所有信息*/ public getPlayer(id: string): NetPlayer { return this._players.get(id); } /**所有玩家*/ public getAllPlayer(): NetPlayer[] { return this.all; } /**将玩家按 location 放到一个数组中,并自定义数组长度*/ public getAllPlayersAtLocations(customLength: number): (NetPlayer | null)[] { const locationArray: (NetPlayer | null)[] = Array(customLength).fill(null); this._players.forEach((player) => { if (player.location >= 0 && player.location < customLength) locationArray[player.location] = player; }); return locationArray; } /**获取除了某个id的所有玩家*/ public getExPlayer(id: string): NetPlayer[] { return Array.from(this._players.values()).filter(player => player.Id != id);; } /**获在线或不在线的所有玩家*/ public getOnlinePlayer(isOnline: boolean): NetPlayer[] { return isOnline ? this.onlines : this.outlines; } /**获准备或没有准备的所有玩家*/ public getReadyPlayer(ready: boolean): NetPlayer[] { return ready ? this.readys : this.notreadys; } public dispose(): void { this._send = null; this._players.forEach((v, _) => { v.dispose(); }); this._players.clear(); } }