import EventTarget from "./EventTarget"; import { PeerInfo } from "./PeerInfo"; import WebRTC from "./WebRTC"; import MWSE from "./index"; interface IPeerOptions{ }; enum IMessageSymbase { PayloadMessagePack = -12873.54, PayloadRTCBasePack = -12884.54 } export default class Peer extends EventTarget { public mwse : MWSE; public options : IPeerOptions = {}; public socketId? : string; public selfSocket : boolean = false; public active : boolean = false; public info : PeerInfo; public rtc? : WebRTC; public peerConnection : boolean = false; public primaryChannel : "websocket" | "datachannel" = "datachannel"; constructor(wsts:MWSE){ super(); this.mwse = wsts; this.info = new PeerInfo(this); this.on('pack',(data:{type?:string,action?:IMessageSymbase,payload?:any}) => { if(data.type == ':rtcbase_pack:') { if(this.rtc) { return this.rtc.emit("input", data.payload) } return console.warn("Not active rtc but recaived rtc packs") }; this.emit("message", data); }); } public createRTC(rtcConfig?: RTCConfiguration | undefined, rtcServers?: RTCIceServer[] | undefined) : WebRTC { this.rtc = new WebRTC(rtcConfig,rtcServers); this.rtc.peer = this; this.rtc.on("connected", () => { this.peerConnection = true; }); this.rtc.on('disconnected', () => { this.peerConnection = false; }) this.rtc.on("output",(payload:object) => { this.send({ type: ':rtcbase_pack:', payload: payload }) }); this.rtc.on("message",(payload:object) => { this.emit("pack",payload); }); return this.rtc; } public setPeerOptions(options: string | IPeerOptions){ if(typeof options == "string") { this.setSocketId(options) }else{ this.options = options; } } public setSocketId(uuid: string){ this.socketId = uuid; } async metadata() : Promise { if(this.socketId == 'me') { let result = await this.mwse.EventPooling.request({ type:'my/socketid' }); this.selfSocket = true; this.active ||= true; this.socketId = result; this.emit('scope'); this.activeScope = true; return result; } }; async request(pack:any){ if(this.active) { return await this.mwse.request(this.socketId as string, pack); } }; equalTo(peer : Peer | {socketId: string}) { return this.socketId == peer.socketId; } async isReachable() { return await this.mwse.EventPooling.request({ type:'is/reachable', to: this.socketId }); } async enablePairAuth(){ await this.mwse.EventPooling.request({ type:'auth/pair-system', value: 'everybody' }); } async disablePairAuth(){ await this.mwse.EventPooling.request({ type:'auth/pair-system', value: 'disable' }); } async enablePairInfo(){ await this.mwse.EventPooling.request({ type: 'connection/pairinfo', value: true }); } async disablePairInfo(){ await this.mwse.EventPooling.request({ type: 'connection/pairinfo', value: false }); } async requestPair() { let {message,status} = await this.mwse.EventPooling.request({ type:'request/pair', to: this.socketId }); if( message == "ALREADY-PAIRED" || message == "ALREADY-REQUESTED" ) { console.warn("Already paired or pair requested") }; if(status == "fail") { console.error("Request Pair Error",status, message); return false; } return true; } async endPair() { await this.mwse.EventPooling.request({ type:'end/pair', to: this.socketId }); this.forget(); } async acceptPair() { let {message,status} = await this.mwse.EventPooling.request({ type:'accept/pair', to: this.socketId }); if(status == "fail") { console.error("Pair Error",status, message); return false; } return true; } async rejectPair() { let {message,status} = await this.mwse.EventPooling.request({ type:'reject/pair', to: this.socketId }); if(status == "fail") { console.error("Pair Error",status, message); return false; } return true; } async getPairedList() : Promise { let {value} = await this.mwse.EventPooling.request({ type:'pair/list', to: this.socketId }); return value; } async send(pack: any){ let isOpenedP2P = this.peerConnection && this.rtc?.active; let isOpenedServer = this.mwse.server.connected; let sendChannel : "websocket" | "datachannel"; if(isOpenedP2P && isOpenedServer) { if(this.primaryChannel == "websocket") { sendChannel = "websocket" }else { sendChannel = "datachannel" } }else if(isOpenedServer){ sendChannel = "websocket" }else{ sendChannel = "datachannel" } if(sendChannel == "websocket") { if(!this.mwse.writable){ return console.warn("Socket is not writable"); } await this.mwse.EventPooling.request({ type:'pack/to', pack, to: this.socketId }); }else{ this.rtc?.sendMessage(pack) } } async forget(){ this.mwse.peers.delete(this.socketId as string); this.mwse.pairs.delete(this.socketId as string); } }