fixes for sp2, part 5

This commit is contained in:
lax1dude 2024-12-08 23:43:32 -08:00
parent 3f648e6692
commit a67841a8f3
5 changed files with 184 additions and 310 deletions

View File

@ -19,10 +19,6 @@ window.initializeVoiceClient = (() => {
const READYSTATE_ABORTED = -1;
const READYSTATE_DEVICE_INITIALIZED = 1;
const PEERSTATE_FAILED = 0;
const PEERSTATE_SUCCESS = 1;
const PEERSTATE_LOADING = 2;
class EaglercraftVoicePeer {
constructor(client, peerId, peerConnection, offer) {
@ -31,52 +27,43 @@ window.initializeVoiceClient = (() => {
this.peerConnection = peerConnection;
this.stream = null;
const self = this;
this.peerConnection.addEventListener("icecandidate", (evt) => {
if(evt.candidate) {
self.client.iceCandidateHandler(self.peerId, JSON.stringify({ sdpMLineIndex: evt.candidate.sdpMLineIndex, candidate: evt.candidate.candidate }));
this.client.iceCandidateHandler(this.peerId, JSON.stringify({ sdpMLineIndex: evt.candidate.sdpMLineIndex, candidate: evt.candidate.candidate }));
}
});
this.peerConnection.addEventListener("track", (evt) => {
self.rawStream = evt.streams[0];
this.rawStream = evt.streams[0];
const aud = new Audio();
aud.autoplay = true;
aud.muted = true;
aud.onended = function() {
aud.remove();
};
aud.srcObject = self.rawStream;
self.client.peerTrackHandler(self.peerId, self.rawStream);
aud.srcObject = this.rawStream;
this.client.peerTrackHandler(this.peerId, this.rawStream);
});
this.peerConnection.addStream(this.client.localMediaStream.stream);
if (offer) {
this.peerConnection.createOffer((desc) => {
const selfDesc = desc;
self.peerConnection.setLocalDescription(selfDesc, () => {
self.client.descriptionHandler(self.peerId, JSON.stringify(selfDesc));
if (self.client.peerStateInitial != PEERSTATE_SUCCESS) self.client.peerStateInitial = PEERSTATE_SUCCESS;
this.peerConnection.setLocalDescription(selfDesc, () => {
this.client.descriptionHandler(this.peerId, JSON.stringify(selfDesc));
}, (err) => {
console.error("Failed to set local description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateInitial == PEERSTATE_LOADING) self.client.peerStateInitial = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
console.error("Failed to set local description for \"" + this.peerId + "\"! " + err);
this.client.signalDisconnect(this.peerId);
});
}, (err) => {
console.error("Failed to set create offer for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateInitial == PEERSTATE_LOADING) self.client.peerStateInitial = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
console.error("Failed to set create offer for \"" + this.peerId + "\"! " + err);
this.client.signalDisconnect(this.peerId);
});
}
this.peerConnection.addEventListener("connectionstatechange", (evt) => {
if(self.peerConnection.connectionState === 'disconnected') {
self.client.signalDisconnect(self.peerId);
} else if (self.peerConnection.connectionState === 'connected') {
if (self.client.peerState != PEERSTATE_SUCCESS) self.client.peerState = PEERSTATE_SUCCESS;
} else if (self.peerConnection.connectionState === 'failed') {
if (self.client.peerState == PEERSTATE_LOADING) self.client.peerState = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
if(this.peerConnection.connectionState === 'disconnected' || this.peerConnection.connectionState === 'failed') {
this.client.signalDisconnect(this.peerId);
}
});
@ -91,46 +78,38 @@ window.initializeVoiceClient = (() => {
}
setRemoteDescription(descJSON) {
const self = this;
try {
const remoteDesc = JSON.parse(descJSON);
this.peerConnection.setRemoteDescription(remoteDesc, () => {
if(remoteDesc.type == 'offer') {
self.peerConnection.createAnswer((desc) => {
if(remoteDesc.type === 'offer') {
this.peerConnection.createAnswer((desc) => {
const selfDesc = desc;
self.peerConnection.setLocalDescription(selfDesc, () => {
self.client.descriptionHandler(self.peerId, JSON.stringify(selfDesc));
if (self.client.peerStateDesc != PEERSTATE_SUCCESS) self.client.peerStateDesc = PEERSTATE_SUCCESS;
this.peerConnection.setLocalDescription(selfDesc, () => {
this.client.descriptionHandler(this.peerId, JSON.stringify(selfDesc));
}, (err) => {
console.error("Failed to set local description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
console.error("Failed to set local description for \"" + this.peerId + "\"! " + err);
this.client.signalDisconnect(this.peerId);
});
}, (err) => {
console.error("Failed to create answer for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
console.error("Failed to create answer for \"" + this.peerId + "\"! " + err);
this.client.signalDisconnect(this.peerId);
});
}
}, (err) => {
console.error("Failed to set remote description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
console.error("Failed to set remote description for \"" + this.peerId + "\"! " + err);
this.client.signalDisconnect(this.peerId);
});
} catch (err) {
console.error("Failed to parse remote description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
console.error("Failed to parse remote description for \"" + this.peerId + "\"! " + err);
this.client.signalDisconnect(this.peerId);
}
}
addICECandidate(candidate) {
try {
this.peerConnection.addIceCandidate(new RTCIceCandidate(JSON.parse(candidate)));
if (this.client.peerStateIce != PEERSTATE_SUCCESS) this.client.peerStateIce = PEERSTATE_SUCCESS;
} catch (err) {
console.error("Failed to parse ice candidate for \"" + this.peerId + "\"! " + err);
if (this.client.peerStateIce == PEERSTATE_LOADING) this.client.peerStateIce = PEERSTATE_FAILED;
this.client.signalDisconnect(this.peerId);
}
}
@ -144,11 +123,6 @@ window.initializeVoiceClient = (() => {
this.hasInit = false;
this.peerList = new Map();
this.readyState = READYSTATE_NONE;
this.peerState = PEERSTATE_LOADING;
this.peerStateConnect = PEERSTATE_LOADING;
this.peerStateInitial = PEERSTATE_LOADING;
this.peerStateDesc = PEERSTATE_LOADING;
this.peerStateIce = PEERSTATE_LOADING;
this.iceCandidateHandler = null;
this.descriptionHandler = null;
this.peerTrackHandler = null;
@ -165,9 +139,9 @@ window.initializeVoiceClient = (() => {
this.ICEServers.length = 0;
for(var i = 0; i < urls.length; ++i) {
var etr = urls[i].split(";");
if(etr.length == 1) {
if(etr.length === 1) {
this.ICEServers.push({ urls: etr[0] });
}else if(etr.length == 3) {
}else if(etr.length === 3) {
this.ICEServers.push({ urls: etr[0], username: etr[1], credential: etr[2] });
}
}
@ -195,21 +169,20 @@ window.initializeVoiceClient = (() => {
initializeDevices() {
if(!this.hasInit) {
const self = this;
navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then((stream) => {
self.microphoneVolumeAudioContext = new AudioContext();
self.localRawMediaStream = stream;
self.localRawMediaStream.getAudioTracks()[0].enabled = false;
self.localMediaStream = self.microphoneVolumeAudioContext.createMediaStreamDestination();
self.localMediaStreamGain = self.microphoneVolumeAudioContext.createGain();
var localStreamIn = self.microphoneVolumeAudioContext.createMediaStreamSource(stream);
localStreamIn.connect(self.localMediaStreamGain);
self.localMediaStreamGain.connect(self.localMediaStream);
self.localMediaStreamGain.gain.value = 1.0;
self.readyState = READYSTATE_DEVICE_INITIALIZED;
this.microphoneVolumeAudioContext = new AudioContext();
this.localRawMediaStream = stream;
this.localRawMediaStream.getAudioTracks()[0].enabled = false;
this.localMediaStream = this.microphoneVolumeAudioContext.createMediaStreamDestination();
this.localMediaStreamGain = this.microphoneVolumeAudioContext.createGain();
var localStreamIn = this.microphoneVolumeAudioContext.createMediaStreamSource(stream);
localStreamIn.connect(this.localMediaStreamGain);
this.localMediaStreamGain.connect(this.localMediaStream);
this.localMediaStreamGain.gain.value = 1.0;
this.readyState = READYSTATE_DEVICE_INITIALIZED;
this.hasInit = true;
}).catch((err) => {
self.readyState = READYSTATE_ABORTED;
this.readyState = READYSTATE_ABORTED;
});
}else {
this.readyState = READYSTATE_DEVICE_INITIALIZED;
@ -225,43 +198,16 @@ window.initializeVoiceClient = (() => {
}
}
resetPeerStates() {
this.peerState = this.peerStateConnect = this.peerStateInitial = this.peerStateDesc = this.peerStateIce = PEERSTATE_LOADING;
}
getPeerState() {
return this.peerState;
}
getPeerStateConnect() {
return this.peerStateConnect;
}
getPeerStateInitial() {
return this.peerStateInitial;
}
getPeerStateDesc() {
return this.peerStateDesc;
}
getPeerStateIce() {
return this.peerStateIce;
}
getReadyState() {
return this.readyState;
}
signalConnect(peerId, offer) {
if (!this.hasInit) this.initializeDevices();
try {
const peerConnection = new RTCPeerConnection({ iceServers: this.ICEServers, optional: [ { DtlsSrtpKeyAgreement: true } ] });
const peerInstance = new EaglercraftVoicePeer(this, peerId, peerConnection, offer);
this.peerList.set(peerId, peerInstance);
if (this.peerStateConnect != PEERSTATE_SUCCESS) this.peerStateConnect = PEERSTATE_SUCCESS;
const peerConnection = new RTCPeerConnection({ iceServers: this.ICEServers, optional: [ { DtlsSrtpKeyAgreement: true } ] });
const peerInstance = new EaglercraftVoicePeer(this, peerId, peerConnection, offer);
this.peerList.set(peerId, peerInstance);
} catch (e) {
if (this.peerStateConnect == PEERSTATE_LOADING) this.peerStateConnect = PEERSTATE_FAILED;
}
}
@ -341,11 +287,11 @@ window.initializeLANClient = (() => {
initializeClient() {
try {
if(this.dataChannel != null) {
if(this.dataChannel !== null) {
this.dataChannel.close();
this.dataChannel = null;
}
if(this.peerConnection != null) {
if(this.peerConnection !== null) {
this.peerConnection.close();
}
this.peerConnection = new RTCPeerConnection({ iceServers: this.ICEServers, optional: [ { DtlsSrtpKeyAgreement: true } ] });
@ -359,9 +305,9 @@ window.initializeLANClient = (() => {
this.ICEServers.length = 0;
for(var i = 0; i < urls.length; ++i) {
var etr = urls[i].split(";");
if(etr.length == 1) {
if(etr.length === 1) {
this.ICEServers.push({ urls: etr[0] });
}else if(etr.length == 3) {
}else if(etr.length === 3) {
this.ICEServers.push({ urls: etr[0], username: etr[1], credential: etr[2] });
}
}
@ -392,7 +338,7 @@ window.initializeLANClient = (() => {
}
sendPacketToServer(buffer) {
if(this.dataChannel != null && this.dataChannel.readyState == "open") {
if(this.dataChannel !== null && this.dataChannel.readyState === "open") {
this.dataChannel.send(buffer);
}else {
this.signalRemoteDisconnect(false);
@ -400,15 +346,14 @@ window.initializeLANClient = (() => {
}
signalRemoteConnect() {
const self = this;
const iceCandidates = [];
this.peerConnection.addEventListener("icecandidate", (evt) => {
if(evt.candidate) {
if(iceCandidates.length == 0) setTimeout(() => {
if(self.peerConnection != null && self.peerConnection.connectionState != "disconnected") {
self.iceCandidateHandler(JSON.stringify(iceCandidates));
if(iceCandidates.length === 0) setTimeout(() => {
if(this.peerConnection !== null && this.peerConnection.connectionState !== "disconnected") {
this.iceCandidateHandler(JSON.stringify(iceCandidates));
iceCandidates.length = 0;
}
}, 3000);
@ -423,36 +368,36 @@ window.initializeLANClient = (() => {
while(iceCandidates.length > 0) {
await new Promise(resolve => setTimeout(resolve, 0));
}
self.remoteDataChannelHandler(self.dataChannel);
this.remoteDataChannelHandler(this.dataChannel);
});
this.dataChannel.addEventListener("message", (evt) => {
self.remotePacketHandler(evt.data);
this.remotePacketHandler(evt.data);
}, false);
this.peerConnection.createOffer((desc) => {
const selfDesc = desc;
self.peerConnection.setLocalDescription(selfDesc, () => {
self.descriptionHandler(JSON.stringify(selfDesc));
this.peerConnection.setLocalDescription(selfDesc, () => {
this.descriptionHandler(JSON.stringify(selfDesc));
}, (err) => {
console.error("Failed to set local description! " + err);
self.readyState = READYSTATE_FAILED;
self.signalRemoteDisconnect(false);
this.readyState = READYSTATE_FAILED;
this.signalRemoteDisconnect(false);
});
}, (err) => {
console.error("Failed to set create offer! " + err);
self.readyState = READYSTATE_FAILED;
self.signalRemoteDisconnect(false);
this.readyState = READYSTATE_FAILED;
this.signalRemoteDisconnect(false);
});
this.peerConnection.addEventListener("connectionstatechange", (evt) => {
if(self.peerConnection.connectionState === 'disconnected') {
self.signalRemoteDisconnect(false);
} else if (self.peerConnection.connectionState === 'connected') {
self.readyState = READYSTATE_CONNECTED;
} else if (self.peerConnection.connectionState === 'failed') {
self.readyState = READYSTATE_FAILED;
self.signalRemoteDisconnect(false);
if(this.peerConnection.connectionState === 'disconnected') {
this.signalRemoteDisconnect(false);
} else if (this.peerConnection.connectionState === 'connected') {
this.readyState = READYSTATE_CONNECTED;
} else if (this.peerConnection.connectionState === 'failed') {
this.readyState = READYSTATE_FAILED;
this.signalRemoteDisconnect(false);
}
});
}
@ -481,11 +426,11 @@ window.initializeLANClient = (() => {
}
signalRemoteDisconnect(quiet) {
if(this.dataChannel != null) {
if(this.dataChannel !== null) {
this.dataChannel.close();
this.dataChannel = null;
}
if(this.peerConnection != null) {
if(this.peerConnection !== null) {
this.peerConnection.close();
}
if(!quiet) this.remoteDisconnectHandler();
@ -510,10 +455,6 @@ window.startLANClient = () => {
window.initializeLANServer = (() => {
const PEERSTATE_FAILED = 0;
const PEERSTATE_SUCCESS = 1;
const PEERSTATE_LOADING = 2;
class EaglercraftLANPeer {
constructor(client, peerId, peerConnection) {
@ -522,15 +463,13 @@ window.initializeLANServer = (() => {
this.peerConnection = peerConnection;
this.dataChannel = null;
const self = this;
const iceCandidates = [];
this.peerConnection.addEventListener("icecandidate", (evt) => {
if(evt.candidate) {
if(iceCandidates.length == 0) setTimeout(() => {
if(self.peerConnection != null && self.peerConnection.connectionState != "disconnected") {
self.client.iceCandidateHandler(self.peerId, JSON.stringify(iceCandidates));
if(iceCandidates.length === 0) setTimeout(() => {
if(this.peerConnection !== null && this.peerConnection.connectionState !== "disconnected") {
this.client.iceCandidateHandler(this.peerId, JSON.stringify(iceCandidates));
iceCandidates.length = 0;
}
}, 3000);
@ -542,28 +481,23 @@ window.initializeLANServer = (() => {
while(iceCandidates.length > 0) {
await new Promise(resolve => setTimeout(resolve, 0));
}
self.dataChannel = evt.channel;
self.client.remoteClientDataChannelHandler(self.peerId, self.dataChannel);
self.dataChannel.addEventListener("message", (evt) => {
self.client.remoteClientPacketHandler(self.peerId, evt.data);
this.dataChannel = evt.channel;
this.client.remoteClientDataChannelHandler(this.peerId, this.dataChannel);
this.dataChannel.addEventListener("message", (evt) => {
this.client.remoteClientPacketHandler(this.peerId, evt.data);
}, false);
}, false);
this.peerConnection.addEventListener("connectionstatechange", (evt) => {
if(self.peerConnection.connectionState === 'disconnected') {
self.client.signalRemoteDisconnect(self.peerId);
} else if (self.peerConnection.connectionState === 'connected') {
if (self.client.peerState != PEERSTATE_SUCCESS) self.client.peerState = PEERSTATE_SUCCESS;
} else if (self.peerConnection.connectionState === 'failed') {
if (self.client.peerState == PEERSTATE_LOADING) self.client.peerState = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
if(this.peerConnection.connectionState === 'disconnected' || this.peerConnection.connectionState === 'failed') {
this.client.signalRemoteDisconnect(this.peerId);
}
});
}
disconnect() {
if(this.dataChannel != null) {
if(this.dataChannel !== null) {
this.dataChannel.close();
this.dataChannel = null;
}
@ -571,36 +505,30 @@ window.initializeLANServer = (() => {
}
setRemoteDescription(descJSON) {
const self = this;
try {
const remoteDesc = JSON.parse(descJSON);
this.peerConnection.setRemoteDescription(remoteDesc, () => {
if(remoteDesc.type == 'offer') {
self.peerConnection.createAnswer((desc) => {
if(remoteDesc.type === 'offer') {
this.peerConnection.createAnswer((desc) => {
const selfDesc = desc;
self.peerConnection.setLocalDescription(selfDesc, () => {
self.client.descriptionHandler(self.peerId, JSON.stringify(selfDesc));
if (self.client.peerStateDesc != PEERSTATE_SUCCESS) self.client.peerStateDesc = PEERSTATE_SUCCESS;
this.peerConnection.setLocalDescription(selfDesc, () => {
this.client.descriptionHandler(this.peerId, JSON.stringify(selfDesc));
}, (err) => {
console.error("Failed to set local description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
console.error("Failed to set local description for \"" + this.peerId + "\"! " + err);
this.client.signalRemoteDisconnect(this.peerId);
});
}, (err) => {
console.error("Failed to create answer for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
console.error("Failed to create answer for \"" + this.peerId + "\"! " + err);
this.client.signalRemoteDisconnect(this.peerId);
});
}
}, (err) => {
console.error("Failed to set remote description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
console.error("Failed to set remote description for \"" + this.peerId + "\"! " + err);
this.client.signalRemoteDisconnect(this.peerId);
});
} catch (err) {
console.error("Failed to parse remote description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
console.error("Failed to parse remote description for \"" + this.peerId + "\"! " + err);
this.client.signalRemoteDisconnect(this.peerId);
}
}
@ -610,10 +538,8 @@ window.initializeLANServer = (() => {
for (let candidate of candidateList) {
this.peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
}
if (this.client.peerStateIce != PEERSTATE_SUCCESS) this.client.peerStateIce = PEERSTATE_SUCCESS;
} catch (err) {
console.error("Failed to parse ice candidate for \"" + this.peerId + "\"! " + err);
if (this.client.peerStateIce == PEERSTATE_LOADING) this.client.peerStateIce = PEERSTATE_FAILED;
this.client.signalRemoteDisconnect(this.peerId);
}
}
@ -626,11 +552,6 @@ window.initializeLANServer = (() => {
this.ICEServers = [];
this.hasInit = false;
this.peerList = new Map();
this.peerState = PEERSTATE_LOADING;
this.peerStateConnect = PEERSTATE_LOADING;
this.peerStateInitial = PEERSTATE_LOADING;
this.peerStateDesc = PEERSTATE_LOADING;
this.peerStateIce = PEERSTATE_LOADING;
this.iceCandidateHandler = null;
this.descriptionHandler = null;
this.remoteClientDataChannelHandler = null;
@ -650,9 +571,9 @@ window.initializeLANServer = (() => {
this.ICEServers.length = 0;
for(var i = 0; i < urls.length; ++i) {
var etr = urls[i].split(";");
if(etr.length == 1) {
if(etr.length === 1) {
this.ICEServers.push({ urls: etr[0] });
}else if(etr.length == 3) {
}else if(etr.length === 3) {
this.ICEServers.push({ urls: etr[0], username: etr[1], credential: etr[2] });
}
}
@ -681,7 +602,7 @@ window.initializeLANServer = (() => {
sendPacketToRemoteClient(peerId, buffer) {
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
if(thePeer.dataChannel != null && thePeer.dataChannel.readyState == "open") {
if(thePeer.dataChannel != null && thePeer.dataChannel.readyState === "open") {
thePeer.dataChannel.send(buffer);
}else {
this.signalRemoteDisconnect(peerId);
@ -689,38 +610,12 @@ window.initializeLANServer = (() => {
}
}
resetPeerStates() {
this.peerState = this.peerStateConnect = this.peerStateInitial = this.peerStateDesc = this.peerStateIce = PEERSTATE_LOADING;
}
getPeerState() {
return this.peerState;
}
getPeerStateConnect() {
return this.peerStateConnect;
}
getPeerStateInitial() {
return this.peerStateInitial;
}
getPeerStateDesc() {
return this.peerStateDesc;
}
getPeerStateIce() {
return this.peerStateIce;
}
signalRemoteConnect(peerId) {
try {
const peerConnection = new RTCPeerConnection({ iceServers: this.ICEServers, optional: [ { DtlsSrtpKeyAgreement: true } ] });
const peerInstance = new EaglercraftLANPeer(this, peerId, peerConnection);
this.peerList.set(peerId, peerInstance);
if (this.peerStateConnect != PEERSTATE_SUCCESS) this.peerStateConnect = PEERSTATE_SUCCESS;
} catch (e) {
if (this.peerStateConnect == PEERSTATE_LOADING) this.peerStateConnect = PEERSTATE_FAILED;
}
}
@ -739,7 +634,7 @@ window.initializeLANServer = (() => {
}
signalRemoteDisconnect(peerId) {
if(peerId.length == 0) {
if(peerId.length === 0) {
for(const thePeer of this.peerList.values()) {
if((typeof thePeer !== "undefined") && thePeer !== null) {
this.peerList.delete(peerId);

View File

@ -177,41 +177,32 @@ public class IntegratedServerLAN {
private static final class LANClient {
private static final int PRE = 0, SENT_ICE_CANDIDATE = 2, SENT_DESCRIPTION = 3, CONNECTED = 4, CLOSED = 5;
private static final int PRE = 0, RECEIVED_ICE_CANDIDATE = 1, SENT_ICE_CANDIDATE = 2, RECEIVED_DESCRIPTION = 3,
SENT_DESCRIPTION = 4, RECEIVED_SUCCESS = 5, CONNECTED = 6, CLOSED = 7;
protected final String clientId;
protected int state = PRE;
protected boolean dead = false;
protected String localICECandidate = null;
protected final long startTime;
protected LANClient(String clientId) {
this.clientId = clientId;
this.startTime = EaglerAdapter.steadyTimeMillis();
EaglerAdapter.serverLANCreatePeer(clientId);
}
protected void handleICECandidates(String candidates) {
if(state == SENT_DESCRIPTION) {
EaglerAdapter.serverLANPeerICECandidates(clientId, candidates);
long millis = EaglerAdapter.steadyTimeMillis();
do {
LANPeerEvent evt;
if((evt = EaglerAdapter.serverLANGetEvent(clientId)) != null) {
if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
lanRelaySocket.writePacket(new IPacket03ICECandidate(clientId, ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates));
state = SENT_ICE_CANDIDATE;
return;
}else if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
System.err.println("LAN client '" + clientId + "' disconnected while waiting for server ICE candidates");
}else {
System.err.println("LAN client '" + clientId + "' had an accident: " + evt.getClass().getSimpleName());
}
disconnect();
return;
}
EaglerAdapter.sleep(20);
}while(EaglerAdapter.steadyTimeMillis() - millis < 5000l);
System.err.println("Getting server ICE candidates for '" + clientId + "' timed out!");
disconnect();
if(localICECandidate != null) {
lanRelaySocket.writePacket(new IPacket03ICECandidate(clientId, localICECandidate));
localICECandidate = null;
state = SENT_ICE_CANDIDATE;
}else {
state = RECEIVED_ICE_CANDIDATE;
}
}else {
System.err.println("Relay [" + lanRelaySocket.getURI() + "] unexpected IPacket03ICECandidate for '" + clientId + "'");
}
@ -220,26 +211,7 @@ public class IntegratedServerLAN {
protected void handleDescription(String description) {
if(state == PRE) {
EaglerAdapter.serverLANPeerDescription(clientId, description);
long millis = EaglerAdapter.steadyTimeMillis();
do {
LANPeerEvent evt;
if((evt = EaglerAdapter.serverLANGetEvent(clientId)) != null) {
if(evt instanceof LANPeerEvent.LANPeerDescriptionEvent) {
lanRelaySocket.writePacket(new IPacket04Description(clientId, ((LANPeerEvent.LANPeerDescriptionEvent)evt).description));
state = SENT_DESCRIPTION;
return;
}else if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
System.err.println("LAN client '" + clientId + "' disconnected while waiting for server description");
}else {
System.err.println("LAN client '" + clientId + "' had an accident: " + evt.getClass().getSimpleName());
}
disconnect();
return;
}
EaglerAdapter.sleep(20);
}while(EaglerAdapter.steadyTimeMillis() - millis < 5000l);
System.err.println("Getting server description for '" + clientId + "' timed out!");
disconnect();
state = RECEIVED_DESCRIPTION;
}else {
System.err.println("Relay [" + lanRelaySocket.getURI() + "] unexpected IPacket04Description for '" + clientId + "'");
}
@ -247,30 +219,7 @@ public class IntegratedServerLAN {
protected void handleSuccess() {
if(state == SENT_ICE_CANDIDATE) {
long millis = EaglerAdapter.steadyTimeMillis();
do {
LANPeerEvent evt;
while((evt = EaglerAdapter.serverLANGetEvent(clientId)) != null && evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
// skip ice candidates
}
if(evt != null) {
if(evt instanceof LANPeerEvent.LANPeerDataChannelEvent) {
EaglerAdapter.enableChannel("NET|" + clientId);
IntegratedServer.sendIPCPacket(new IPCPacket0CPlayerChannel(clientId, true));
state = CONNECTED;
return;
}else if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
System.err.println("LAN client '" + clientId + "' disconnected while waiting for connection");
}else {
System.err.println("LAN client '" + clientId + "' had an accident: " + evt.getClass().getSimpleName());
}
disconnect();
return;
}
EaglerAdapter.sleep(20);
}while(EaglerAdapter.steadyTimeMillis() - millis < 5000l);
System.err.println("Getting server description for '" + clientId + "' timed out!");
disconnect();
state = RECEIVED_SUCCESS;
}else {
System.err.println("Relay [" + lanRelaySocket.getURI() + "] unexpected IPacket05ClientSuccess for '" + clientId + "'");
}
@ -286,23 +235,70 @@ public class IntegratedServerLAN {
}
protected void update() {
if(state == CONNECTED) {
PKT pk;
while(state == CONNECTED && (pk = EaglerAdapter.recieveFromIntegratedServer("NET|" + clientId)) != null) {
EaglerAdapter.serverLANWritePacket(clientId, pk.data);
if(state != CLOSED) {
if(state != CONNECTED && EaglerAdapter.steadyTimeMillis() - startTime > 13000l) {
System.out.println("LAN client '" + clientId + "' handshake timed out");
disconnect();
return;
}
LANPeerEvent evt;
while(state == CONNECTED && (evt = EaglerAdapter.serverLANGetEvent(clientId)) != null) {
if(evt instanceof LANPeerEvent.LANPeerPacketEvent) {
EaglerAdapter.sendToIntegratedServer("NET|" + clientId, ((LANPeerEvent.LANPeerPacketEvent)evt).payload);
}else if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
List<LANPeerEvent> l = EaglerAdapter.serverLANGetAllEvent(clientId);
if(l == null) {
return;
}
read_loop: for(int i = 0, s = l.size(); i < s; ++i) {
LANPeerEvent evt = l.get(i);
if(evt instanceof LANPeerEvent.LANPeerDisconnectEvent) {
System.out.println("LAN client '" + clientId + "' disconnected");
disconnect();
}else {
System.err.println("LAN client '" + clientId + "' had an accident: " + evt.getClass().getSimpleName());
switch(state) {
case SENT_DESCRIPTION:{
if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
localICECandidate = ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates;
continue read_loop;
}
}
case RECEIVED_ICE_CANDIDATE: {
if(evt instanceof LANPeerEvent.LANPeerICECandidateEvent) {
lanRelaySocket.writePacket(new IPacket03ICECandidate(clientId, ((LANPeerEvent.LANPeerICECandidateEvent)evt).candidates));
state = SENT_ICE_CANDIDATE;
continue read_loop;
}
}
case RECEIVED_DESCRIPTION: {
if(evt instanceof LANPeerEvent.LANPeerDescriptionEvent) {
lanRelaySocket.writePacket(new IPacket04Description(clientId, ((LANPeerEvent.LANPeerDescriptionEvent)evt).description));
state = SENT_DESCRIPTION;
continue read_loop;
}
}
case SENT_ICE_CANDIDATE:
case RECEIVED_SUCCESS: {
if(evt instanceof LANPeerEvent.LANPeerDataChannelEvent) {
EaglerAdapter.enableChannel("NET|" + clientId);
state = CONNECTED;
continue read_loop;
}
}
case CONNECTED: {
if(evt instanceof LANPeerEvent.LANPeerPacketEvent) {
EaglerAdapter.sendToIntegratedServer("NET|" + clientId, ((LANPeerEvent.LANPeerPacketEvent)evt).payload);
continue read_loop;
}
}
default: {
break;
}
}
if(state != CLOSED) {
System.err.println("LAN client '" + clientId + "' had an accident: " + evt.getClass().getSimpleName());
}
disconnect();
return;
}
}
}else {
disconnect();
}
}

View File

@ -58,7 +58,6 @@ import org.teavm.jso.dom.html.HTMLVideoElement;
import org.teavm.jso.media.MediaError;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.DataView;
import org.teavm.jso.typedarrays.Float32Array;
import org.teavm.jso.typedarrays.Int32Array;
import org.teavm.jso.typedarrays.Uint8Array;
import org.teavm.jso.typedarrays.Uint8ClampedArray;
@ -2632,7 +2631,6 @@ public class EaglerAdapterImpl2 {
public static final void enableVoice(Voice.VoiceChannel enable) {
if (enabledChannel == enable) return;
voiceClient.resetPeerStates();
if (enabledChannel == Voice.VoiceChannel.PROXIMITY) {
for (String username : nearbyPlayers) voiceClient.signalDisconnect(username, false);
for (String username : recentlyNearbyPlayers) voiceClient.signalDisconnect(username, false);
@ -2752,13 +2750,10 @@ public class EaglerAdapterImpl2 {
public static final Voice.VoiceChannel getVoiceChannel() {
return enabledChannel;
}
public static final boolean voicePeerErrored() {
return voiceClient.getPeerState() == EaglercraftVoiceClient.PEERSTATE_FAILED || voiceClient.getPeerStateConnect() == EaglercraftVoiceClient.PEERSTATE_FAILED || voiceClient.getPeerStateInitial() == EaglercraftVoiceClient.PEERSTATE_FAILED || voiceClient.getPeerStateDesc() == EaglercraftVoiceClient.PEERSTATE_FAILED || voiceClient.getPeerStateIce() == EaglercraftVoiceClient.PEERSTATE_FAILED;
}
public static final Voice.VoiceStatus getVoiceStatus() {
return (!voiceAvailable() || !voiceAllowed()) ? Voice.VoiceStatus.UNAVAILABLE :
(voiceClient.getReadyState() != EaglercraftVoiceClient.READYSTATE_DEVICE_INITIALIZED ?
Voice.VoiceStatus.CONNECTING : (voicePeerErrored() ? Voice.VoiceStatus.UNAVAILABLE : Voice.VoiceStatus.CONNECTED));
Voice.VoiceStatus.CONNECTING : Voice.VoiceStatus.CONNECTED);
}
private static boolean talkStatus = false;
@ -4259,6 +4254,26 @@ public class EaglerAdapterImpl2 {
}
}
public static final List<LANPeerEvent> serverLANGetAllEvent(String clientId) {
if(serverLANEventBuffer.size() > 0) {
List<LANPeerEvent> lst = null;
Iterator<LANPeerEvent> i = serverLANEventBuffer.iterator();
while(i.hasNext()) {
LANPeerEvent evt = i.next();
if(evt.getPeerId().equals(clientId)) {
i.remove();
if(lst == null) {
lst = new ArrayList<>();
}
lst.add(evt);
}
}
return lst;
}else {
return null;
}
}
private static final int fragmentSize = 65536;
public static final void serverLANWritePacket(String peer, byte[] data) {

View File

@ -6,10 +6,6 @@ import org.teavm.jso.typedarrays.ArrayBuffer;
public interface EaglercraftLANServer extends JSObject {
final int PEERSTATE_FAILED = 0;
final int PEERSTATE_SUCCESS = 1;
final int PEERSTATE_LOADING = 2;
boolean LANServerSupported();
void initializeServer();
@ -28,18 +24,6 @@ public interface EaglercraftLANServer extends JSObject {
void sendPacketToRemoteClient(String peerId, ArrayBuffer buffer);
void resetPeerStates();
int getPeerState();
int getPeerStateConnect();
int getPeerStateInitial();
int getPeerStateDesc();
int getPeerStateIce();
void signalRemoteConnect(String peerId);
void signalRemoteDescription(String peerId, String descJSON);

View File

@ -10,10 +10,6 @@ public interface EaglercraftVoiceClient extends JSObject {
int READYSTATE_ABORTED = -1;
int READYSTATE_DEVICE_INITIALIZED = 1;
int PEERSTATE_FAILED = 0;
int PEERSTATE_SUCCESS = 1;
int PEERSTATE_LOADING = 2;
boolean voiceClientSupported();
void initializeDevices();
@ -34,18 +30,6 @@ public interface EaglercraftVoiceClient extends JSObject {
void mutePeer(String peerId, boolean muted);
void resetPeerStates();
int getPeerState();
int getPeerStateConnect();
int getPeerStateInitial();
int getPeerStateDesc();
int getPeerStateIce();
int getReadyState();
int signalConnect(String peerId, boolean offer);