LAN stuff (WIP)
This commit is contained in:
parent
d01c6fb300
commit
fa4c20e4d1
|
@ -324,59 +324,137 @@ window.initializeLANClient = (() => {
|
||||||
class EaglercraftLANClient {
|
class EaglercraftLANClient {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.ICEServers = [];
|
||||||
|
this.peerConnection = null;
|
||||||
|
this.dataChannel = null;
|
||||||
|
this.readyState = READYSTATE_CONNECTING;
|
||||||
|
this.iceCandidateHandler = null;
|
||||||
|
this.descriptionHandler = null;
|
||||||
|
this.remoteDataChannelHandler = null;
|
||||||
|
this.remoteDisconnectHandler = null;
|
||||||
|
this.remotePacketHandler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
LANClientSupported() {
|
LANClientSupported() {
|
||||||
|
return typeof window.RTCPeerConnection !== "undefined";
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeClient() {
|
initializeClient() {
|
||||||
|
try {
|
||||||
|
if(this.dataChannel != null) {
|
||||||
|
this.dataChannel.close();
|
||||||
|
this.dataChannel = null;
|
||||||
|
}
|
||||||
|
if(this.peerConnection != null) {
|
||||||
|
this.peerConnection.close();
|
||||||
|
this.peerConnection = null;
|
||||||
|
}
|
||||||
|
this.peerConnection = new RTCPeerConnection({ iceServers: this.ICEServers, optional: [ { DtlsSrtpKeyAgreement: true } ] });
|
||||||
|
this.readyState = READYSTATE_CONNECTING;
|
||||||
|
} catch (e) {
|
||||||
|
this.readyState = READYSTATE_INIT_FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setICEServers(urls) {
|
setICEServers(urls) {
|
||||||
|
this.ICEServers.length = 0;
|
||||||
|
for(var i = 0; i < urls.length; ++i) {
|
||||||
|
var etr = urls[i].split(";");
|
||||||
|
if(etr.length == 1) {
|
||||||
|
this.ICEServers.push({ urls: etr[0] });
|
||||||
|
}else if(etr.length == 3) {
|
||||||
|
this.ICEServers.push({ urls: etr[0], username: etr[1], credential: etr[2] });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setICECandidateHandler(cb) {
|
setICECandidateHandler(cb) {
|
||||||
|
this.iceCandidateHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
setDescriptionHandler(cb) {
|
setDescriptionHandler(cb) {
|
||||||
|
this.descriptionHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
setRemoteDataChannelHandler(cb) {
|
setRemoteDataChannelHandler(cb) {
|
||||||
|
this.remoteDataChannelHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
setRemoteDisconnectHandler(cb) {
|
setRemoteDisconnectHandler(cb) {
|
||||||
|
this.remoteDisconnectHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
setRemotePacketHandler(cb) {
|
setRemotePacketHandler(cb) {
|
||||||
|
this.remotePacketHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
getReadyState() {
|
getReadyState() {
|
||||||
|
return this.readyState;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPacketToServer(buffer) {
|
sendPacketToServer(buffer) {
|
||||||
|
this.dataChannel.send(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
signalRemoteConnect() {
|
signalRemoteConnect() {
|
||||||
|
const self = this;
|
||||||
|
this.peerConnection.addEventListener("icecandidate", (evt) => {
|
||||||
|
if(evt.candidate) {
|
||||||
|
self.iceCandidateHandler(JSON.stringify({ sdpMLineIndex: evt.candidate.sdpMLineIndex, candidate: evt.candidate.candidate }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.peerConnection.addEventListener("datachannel", (evt) => {
|
||||||
|
self.channel = evt.channel;
|
||||||
|
self.remoteDataChannelHandler(self.channel);
|
||||||
|
evt.channel.addEventListener("message", (evt) => {
|
||||||
|
self.remotePacketHandler(evt.data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.peerConnection.createOffer((desc) => {
|
||||||
|
const selfDesc = desc;
|
||||||
|
self.peerConnection.setLocalDescription(selfDesc, () => {
|
||||||
|
self.descriptionHandler(JSON.stringify(selfDesc));
|
||||||
|
}, (err) => {
|
||||||
|
console.error("Failed to set local description! " + err);
|
||||||
|
self.readyState = READYSTATE_FAILED;
|
||||||
|
self.signalRemoteDisconnect();
|
||||||
|
});
|
||||||
|
}, (err) => {
|
||||||
|
console.error("Failed to set create offer! " + err);
|
||||||
|
self.readyState = READYSTATE_FAILED;
|
||||||
|
self.signalRemoteDisconnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.peerConnection.addEventListener("connectionstatechange", (evt) => {
|
||||||
|
if(evt.connectionState === 'disconnected') {
|
||||||
|
self.signalRemoteDisconnect();
|
||||||
|
} else if (evt.connectionState === 'connected') {
|
||||||
|
self.readyState = READYSTATE_CONNECTED;
|
||||||
|
} else if (evt.connectionState === 'failed') {
|
||||||
|
self.readyState = READYSTATE_FAILED;
|
||||||
|
self.signalRemoteDisconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
signalRemoteDescription(descJSON) {
|
signalRemoteDescription(descJSON) {
|
||||||
|
this.peerConnection.setRemoteDescription(descJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
signalRemoteICECandidate(candidate) {
|
signalRemoteICECandidate(candidate) {
|
||||||
|
this.peerConnection.addICECandidate(candidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
signalRemoteDisconnect() {
|
||||||
|
if(this.dataChannel != null) {
|
||||||
|
this.dataChannel.close();
|
||||||
|
this.dataChannel = null;
|
||||||
|
}
|
||||||
|
this.peerConnection.close();
|
||||||
|
this.remoteDisconnectHandler();
|
||||||
|
this.readyState = READYSTATE_DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -397,66 +475,244 @@ window.startLANClient = () => {
|
||||||
|
|
||||||
window.initializeLANServer = (() => {
|
window.initializeLANServer = (() => {
|
||||||
|
|
||||||
|
const PEERSTATE_FAILED = 0;
|
||||||
|
const PEERSTATE_SUCCESS = 1;
|
||||||
|
const PEERSTATE_LOADING = 2;
|
||||||
|
|
||||||
|
class EaglercraftLANPeer {
|
||||||
|
|
||||||
|
constructor(client, peerId, peerConnection) {
|
||||||
|
this.client = client;
|
||||||
|
this.peerId = peerId;
|
||||||
|
this.peerConnection = peerConnection;
|
||||||
|
this.dataChannel = 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.dataChannel = this.peerConnection.createDataChannel("lan");
|
||||||
|
|
||||||
|
this.dataChannel.addEventListener("open", (evt) => {
|
||||||
|
self.client.remoteClientDataChannelHandler(self.peerId, this.dataChannel);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.dataChannel.addEventListener("message", (evt) => {
|
||||||
|
self.client.remoteClientPacketHandler(self.peerId, evt.data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.peerConnection.addEventListener("connectionstatechange", (evt) => {
|
||||||
|
if(evt.connectionState === 'disconnected') {
|
||||||
|
self.client.signalRemoteDisconnect(self.peerId);
|
||||||
|
} else if (evt.connectionState === 'connected') {
|
||||||
|
if (self.client.peerState != PEERSTATE_SUCCESS) self.client.peerState = PEERSTATE_SUCCESS;
|
||||||
|
} else if (evt.connectionState === 'failed') {
|
||||||
|
if (self.client.peerState == PEERSTATE_LOADING) self.client.peerState = PEERSTATE_FAILED;
|
||||||
|
self.client.signalRemoteDisconnect(self.peerId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
if(this.dataChannel != null) {
|
||||||
|
this.dataChannel.close();
|
||||||
|
this.dataChannel = null;
|
||||||
|
}
|
||||||
|
this.peerConnection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
setRemoteDescription(descJSON) {
|
||||||
|
const self = this;
|
||||||
|
try {
|
||||||
|
const remoteDesc = JSON.parse(descJSON);
|
||||||
|
this.peerConnection.setRemoteDescription(remoteDesc, () => {
|
||||||
|
if(remoteDesc.type == 'offer') {
|
||||||
|
self.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;
|
||||||
|
}, (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);
|
||||||
|
});
|
||||||
|
}, (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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, (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);
|
||||||
|
});
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.signalRemoteDisconnect(this.peerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class EaglercraftLANServer {
|
class EaglercraftLANServer {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.ICEServers = [];
|
||||||
|
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.remoteClientDataChannelHandler = null;
|
||||||
|
this.remoteClientDisconnectHandler = null;
|
||||||
|
this.remoteClientPacketHandler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
LANServerSupported() {
|
LANServerSupported() {
|
||||||
|
return typeof window.RTCPeerConnection !== "undefined";
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeServer() {
|
initializeServer() {
|
||||||
|
// nothing to do!
|
||||||
}
|
}
|
||||||
|
|
||||||
setRecieveCodeHandler(cb) {
|
setRecieveCodeHandler(cb) {
|
||||||
|
// not yet implemented!
|
||||||
}
|
}
|
||||||
|
|
||||||
setICEServers(urls) {
|
setICEServers(urls) {
|
||||||
|
this.ICEServers.length = 0;
|
||||||
|
for(var i = 0; i < urls.length; ++i) {
|
||||||
|
var etr = urls[i].split(";");
|
||||||
|
if(etr.length == 1) {
|
||||||
|
this.ICEServers.push({ urls: etr[0] });
|
||||||
|
}else if(etr.length == 3) {
|
||||||
|
this.ICEServers.push({ urls: etr[0], username: etr[1], credential: etr[2] });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setICECandidateHandler(cb) {
|
setICECandidateHandler(cb) {
|
||||||
|
this.iceCandidateHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
setDescriptionHandler(cb) {
|
setDescriptionHandler(cb) {
|
||||||
|
this.descriptionHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
setRemoteClientDataChannelHandler(cb) {
|
setRemoteClientDataChannelHandler(cb) {
|
||||||
|
this.remoteClientDataChannelHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
setRemoteClientDisconnectHandler(cb) {
|
setRemoteClientDisconnectHandler(cb) {
|
||||||
|
this.remoteClientDisconnectHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
setRemoteClientPacketHandler(cb) {
|
setRemoteClientPacketHandler(cb) {
|
||||||
|
this.remoteClientPacketHandler = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPacketToRemoteClient(peerId, buffer) {
|
sendPacketToRemoteClient(peerId, buffer) {
|
||||||
|
var thePeer = this.peerList.get(peerId);
|
||||||
|
if((typeof thePeer !== "undefined") && thePeer !== null) {
|
||||||
|
thePeer.dataChannel.send(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signalRemoteDescription(peerId, descJSON) {
|
signalRemoteDescription(peerId, descJSON) {
|
||||||
|
var thePeer = this.peerList.get(peerId);
|
||||||
|
if((typeof thePeer !== "undefined") && thePeer !== null) {
|
||||||
|
thePeer.setRemoteDescription(descJSON);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signalRemoteICECandidate(peerId, candidate) {
|
signalRemoteICECandidate(peerId, candidate) {
|
||||||
|
var thePeer = this.peerList.get(peerId);
|
||||||
|
if((typeof thePeer !== "undefined") && thePeer !== null) {
|
||||||
|
thePeer.addICECandidate(candidate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectRemotePeer(peerId) {
|
signalRemoteDisconnect(peerId) {
|
||||||
|
if(peerId.length == 0) {
|
||||||
|
for(const thePeer of this.peerList.values()) {
|
||||||
|
if((typeof thePeer !== "undefined") && thePeer !== null) {
|
||||||
|
this.peerList.delete(thePeer);
|
||||||
|
try {
|
||||||
|
thePeer.disconnect();
|
||||||
|
}catch(e) {}
|
||||||
|
this.remoteClientDisconnectHandler(peerId, quiet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.peerList.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var thePeer = this.peerList.get(peerId);
|
||||||
|
if((typeof thePeer !== "undefined") && thePeer !== null) {
|
||||||
|
this.peerList.delete(thePeer);
|
||||||
|
try {
|
||||||
|
thePeer.disconnect();
|
||||||
|
}catch(e) {}
|
||||||
|
this.remoteClientDisconnectHandler(peerId, quiet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2934,11 +2934,14 @@ public class EaglerAdapterImpl2 {
|
||||||
return !isLittleEndian;
|
return !isLittleEndian;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EaglercraftLANClient rtcLANClient = null; //TODO
|
private static EaglercraftLANClient rtcLANClient = null;
|
||||||
|
|
||||||
@JSBody(params = { }, script = "return window.startLANClient();")
|
@JSBody(params = { }, script = "return window.startLANClient();")
|
||||||
private static native EaglercraftLANClient startRTCLANClient();
|
private static native EaglercraftLANClient startRTCLANClient();
|
||||||
|
|
||||||
|
private static boolean clientLANinit = false;
|
||||||
|
private static final List<byte[]> clientLANPacketBuffer = new ArrayList<>();
|
||||||
|
|
||||||
public static final int LAN_CLIENT_INIT_FAILED = -2;
|
public static final int LAN_CLIENT_INIT_FAILED = -2;
|
||||||
public static final int LAN_CLIENT_FAILED = -1;
|
public static final int LAN_CLIENT_FAILED = -1;
|
||||||
public static final int LAN_CLIENT_DISCONNECTED = 0;
|
public static final int LAN_CLIENT_DISCONNECTED = 0;
|
||||||
|
@ -2946,27 +2949,67 @@ public class EaglerAdapterImpl2 {
|
||||||
public static final int LAN_CLIENT_CONNECTED = 2;
|
public static final int LAN_CLIENT_CONNECTED = 2;
|
||||||
|
|
||||||
public static final boolean clientLANSupported() {
|
public static final boolean clientLANSupported() {
|
||||||
return true;
|
return rtcLANClient.LANClientSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void clientLANSetServer(String relay, String peerId) {
|
public static final void clientLANSetServer(String relay, String peerId) {
|
||||||
|
if(!clientLANinit) {
|
||||||
|
clientLANinit = true;
|
||||||
|
rtcLANClient.setDescriptionHandler(new EaglercraftLANClient.DescriptionHandler() {
|
||||||
|
@Override
|
||||||
|
public void call(String description) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANClient.setICECandidateHandler(new EaglercraftLANClient.ICECandidateHandler() {
|
||||||
|
@Override
|
||||||
|
public void call(String candidate) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANClient.setRemoteDataChannelHandler(new EaglercraftLANClient.ClientSignalHandler() {
|
||||||
|
@Override
|
||||||
|
public void call() {
|
||||||
|
// basically useless, ignore for now.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANClient.setRemotePacketHandler(new EaglercraftLANClient.RemotePacketHandler() {
|
||||||
|
@Override
|
||||||
|
public void call(ArrayBuffer buffer) {
|
||||||
|
Uint8Array array = Uint8Array.create(buffer);
|
||||||
|
byte[] ret = new byte[array.getByteLength()];
|
||||||
|
for(int i = 0; i < ret.length; ++i) {
|
||||||
|
ret[i] = (byte) array.get(i);
|
||||||
|
}
|
||||||
|
clientLANPacketBuffer.add(ret);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANClient.setRemoteDisconnectHandler(new EaglercraftLANClient.ClientSignalHandler() {
|
||||||
|
@Override
|
||||||
|
public void call() {
|
||||||
|
// disconnected
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// todo: java-side: register with relay and set server
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int clientLANReadyState() {
|
public static final int clientLANReadyState() {
|
||||||
return 0;
|
return rtcLANClient.getReadyState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void clientLANCloseConnection() {
|
public static final void clientLANCloseConnection() {
|
||||||
|
rtcLANClient.signalRemoteDisconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void clientLANSendPacket(byte[] pkt) {
|
public static final void clientLANSendPacket(byte[] pkt) {
|
||||||
|
ArrayBuffer arr = ArrayBuffer.create(pkt.length);
|
||||||
|
Uint8Array.create(arr).set(pkt);
|
||||||
|
rtcLANClient.sendPacketToServer(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final byte[] clientLANReadPacket() {
|
public static final byte[] clientLANReadPacket() {
|
||||||
return null;
|
return clientLANPacketBuffer.size() > 0 ? clientLANPacketBuffer.remove(0) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EaglercraftLANServer rtcLANServer = null;
|
private static EaglercraftLANServer rtcLANServer = null;
|
||||||
|
@ -2974,11 +3017,60 @@ public class EaglerAdapterImpl2 {
|
||||||
@JSBody(params = { }, script = "return window.startLANServer();")
|
@JSBody(params = { }, script = "return window.startLANServer();")
|
||||||
private static native EaglercraftLANServer startRTCLANServer();
|
private static native EaglercraftLANServer startRTCLANServer();
|
||||||
|
|
||||||
|
private static boolean serverLANinit = false;
|
||||||
|
private static final List<LANPeerPacket> serverLANPacketBuffer = new ArrayList<>();
|
||||||
|
|
||||||
public static final boolean serverLANSupported() {
|
public static final boolean serverLANSupported() {
|
||||||
return true;
|
return rtcLANServer.LANServerSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String serverLANInitializeServer(String relay) {
|
public static final String serverLANInitializeServer(String relay) {
|
||||||
|
rtcLANServer.initializeServer();
|
||||||
|
if(!serverLANinit) {
|
||||||
|
serverLANinit = true;
|
||||||
|
rtcLANServer.setDescriptionHandler(new EaglercraftLANServer.DescriptionHandler() {
|
||||||
|
@Override
|
||||||
|
public void call(String peerId, String candidate) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANServer.setICECandidateHandler(new EaglercraftLANServer.ICECandidateHandler() {
|
||||||
|
@Override
|
||||||
|
public void call(String peerId, String candidate) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANServer.setRecieveCodeHandler(new EaglercraftLANServer.CodeHandler() {
|
||||||
|
@Override
|
||||||
|
public void call(String code) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANServer.setRemoteClientDataChannelHandler(new EaglercraftLANServer.ClientSignalHandler() {
|
||||||
|
@Override
|
||||||
|
public void call() {
|
||||||
|
// unused
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANServer.setRemoteClientPacketHandler(new EaglercraftLANServer.PeerPacketHandler() {
|
||||||
|
@Override
|
||||||
|
public void call(String peerId, ArrayBuffer buffer) {
|
||||||
|
Uint8Array array = Uint8Array.create(buffer);
|
||||||
|
byte[] ret = new byte[array.getByteLength()];
|
||||||
|
for(int i = 0; i < ret.length; ++i) {
|
||||||
|
ret[i] = (byte) array.get(i);
|
||||||
|
}
|
||||||
|
serverLANPacketBuffer.add(new LANPeerPacket(peerId, ret));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rtcLANServer.setRemoteClientDisconnectHandler(new EaglercraftLANServer.ClientSignalHandler() {
|
||||||
|
@Override
|
||||||
|
public void call() {
|
||||||
|
// disconnected
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// todo: java-side: register in relay & return code!!
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2987,7 +3079,8 @@ public class EaglerAdapterImpl2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void serverLANCloseServer() {
|
public static final void serverLANCloseServer() {
|
||||||
|
rtcLANServer.signalRemoteDisconnect("");
|
||||||
|
// todo: java-side: disconnect from relay server
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface LANConnectionEvent {
|
public static interface LANConnectionEvent {
|
||||||
|
@ -3022,15 +3115,17 @@ public class EaglerAdapterImpl2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final LANPeerPacket serverLANReadPacket() {
|
public static final LANPeerPacket serverLANReadPacket() {
|
||||||
return null;
|
return serverLANPacketBuffer.size() > 0 ? serverLANPacketBuffer.remove(0) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void serverLANWritePacket(String peer, byte[] data) {
|
public static final void serverLANWritePacket(String peer, byte[] data) {
|
||||||
|
ArrayBuffer arr = ArrayBuffer.create(data.length);
|
||||||
|
Uint8Array.create(arr).set(data);
|
||||||
|
rtcLANServer.sendPacketToRemoteClient(peer, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void serverLANDisconnectPeer(String peer) {
|
public static final void serverLANDisconnectPeer(String peer) {
|
||||||
|
rtcLANServer.signalRemoteDisconnect(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ public interface EaglercraftLANClient extends JSObject {
|
||||||
|
|
||||||
void signalRemoteICECandidate(String candidate);
|
void signalRemoteICECandidate(String candidate);
|
||||||
|
|
||||||
|
void signalRemoteDisconnect();
|
||||||
|
|
||||||
@JSFunctor
|
@JSFunctor
|
||||||
public static interface ICECandidateHandler extends JSObject {
|
public static interface ICECandidateHandler extends JSObject {
|
||||||
void call(String candidate);
|
void call(String candidate);
|
||||||
|
@ -45,7 +47,7 @@ public interface EaglercraftLANClient extends JSObject {
|
||||||
|
|
||||||
@JSFunctor
|
@JSFunctor
|
||||||
public static interface DescriptionHandler extends JSObject {
|
public static interface DescriptionHandler extends JSObject {
|
||||||
void call(String candidate);
|
void call(String description);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSFunctor
|
@JSFunctor
|
||||||
|
|
|
@ -6,6 +6,10 @@ import org.teavm.jso.typedarrays.ArrayBuffer;
|
||||||
|
|
||||||
public interface EaglercraftLANServer extends JSObject {
|
public interface EaglercraftLANServer extends JSObject {
|
||||||
|
|
||||||
|
final int PEERSTATE_FAILED = 0;
|
||||||
|
final int PEERSTATE_SUCCESS = 1;
|
||||||
|
final int PEERSTATE_LOADING = 2;
|
||||||
|
|
||||||
boolean LANServerSupported();
|
boolean LANServerSupported();
|
||||||
|
|
||||||
void initializeServer();
|
void initializeServer();
|
||||||
|
@ -24,7 +28,19 @@ public interface EaglercraftLANServer extends JSObject {
|
||||||
|
|
||||||
void setRemoteClientPacketHandler(PeerPacketHandler cb);
|
void setRemoteClientPacketHandler(PeerPacketHandler cb);
|
||||||
|
|
||||||
void ssendPacketToRemoteClient(String peerId, ArrayBuffer buffer);
|
void sendPacketToRemoteClient(String peerId, ArrayBuffer buffer);
|
||||||
|
|
||||||
|
void resetPeerStates();
|
||||||
|
|
||||||
|
int getPeerState();
|
||||||
|
|
||||||
|
int getPeerStateConnect();
|
||||||
|
|
||||||
|
int getPeerStateInitial();
|
||||||
|
|
||||||
|
int getPeerStateDesc();
|
||||||
|
|
||||||
|
int getPeerStateIce();
|
||||||
|
|
||||||
void signalRemoteConnect(String peerId);
|
void signalRemoteConnect(String peerId);
|
||||||
|
|
||||||
|
@ -32,7 +48,7 @@ public interface EaglercraftLANServer extends JSObject {
|
||||||
|
|
||||||
void signalRemoteICECandidate(String peerId, String candidate);
|
void signalRemoteICECandidate(String peerId, String candidate);
|
||||||
|
|
||||||
void disconnectRemotePeer(String peerId);
|
void signalRemoteDisconnect(String peerId);
|
||||||
|
|
||||||
@JSFunctor
|
@JSFunctor
|
||||||
public static interface ICECandidateHandler extends JSObject {
|
public static interface ICECandidateHandler extends JSObject {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user