229 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			229 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
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.rtc = this.createRTC();
 | 
						|
        this.info = new PeerInfo(this);
 | 
						|
        this.on('pack',(data:{type?:string,action?:IMessageSymbase,payload?:any}) => {
 | 
						|
            if(data.type == ':rtcpack:')
 | 
						|
            {
 | 
						|
                return this.rtc.emit("input", data.payload)
 | 
						|
            };
 | 
						|
            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: ':rtcpack:',
 | 
						|
                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<any>
 | 
						|
    {
 | 
						|
        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<string>
 | 
						|
    {
 | 
						|
        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);
 | 
						|
    }
 | 
						|
}   
 |