Add files via upload

This commit is contained in:
Preston 2024-01-26 10:50:42 -08:00 committed by GitHub
parent 230e8b885d
commit 262603deb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 36773 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,2 @@
# PrecisionClient-Static
The static web files for Precision Client

View File

@ -0,0 +1 @@
!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=93)}({3:function(t,e,n){"use strict";n.d(e,"a",(function(){return r})),n.d(e,"c",(function(){return o})),n.d(e,"g",(function(){return i})),n.d(e,"j",(function(){return a})),n.d(e,"i",(function(){return d})),n.d(e,"b",(function(){return f})),n.d(e,"k",(function(){return u})),n.d(e,"d",(function(){return p})),n.d(e,"e",(function(){return l})),n.d(e,"f",(function(){return m})),n.d(e,"h",(function(){return v}));var r={images:["bmp","jpeg","jpg","ttf","pict","svg","webp","eps","svgz","gif","png","ico","tif","tiff","bpg","avif","jxl"],video:["mp4","3gp","webm","mkv","flv","f4v","f4p","f4bogv","drc","avi","mov","qt","wmv","amv","mpg","mp2","mpeg","mpe","m2v","m4v","3g2","gifv","mpv","av1","ts","tsv","tsa","m2t","m3u8"],audio:["mid","midi","aac","aiff","flac","m4a","m4p","mp3","ogg","oga","mogg","opus","ra","rm","wav","webm","f4a","pat"],interchange:["json","yaml","xml","csv","toml","ini","bson","asn1","ubj"],archives:["jar","iso","tar","tgz","tbz2","tlz","gz","bz2","xz","lz","z","7z","apk","dmg","rar","lzma","txz","zip","zipx"],documents:["pdf","ps","doc","docx","ppt","pptx","xls","otf","xlsx"],other:["srt","swf"]},o=["js","cjs","mjs","css"],c="arc:",i={COMLINK_INIT:"".concat(c,"comlink:init"),NODE_ID:"".concat(c,":nodeId"),CLIENT_TEARDOWN:"".concat(c,"client:teardown"),CLIENT_TAB_ID:"".concat(c,"client:tabId"),CDN_CONFIG:"".concat(c,"cdn:config"),P2P_CLIENT_READY:"".concat(c,"cdn:ready"),STORED_FIDS:"".concat(c,"cdn:storedFids"),SW_HEALTH_CHECK:"".concat(c,"cdn:healthCheck"),WIDGET_CONFIG:"".concat(c,"widget:config"),WIDGET_INIT:"".concat(c,"widget:init"),WIDGET_UI_LOAD:"".concat(c,"widget:load"),BROKER_LOAD:"".concat(c,"broker:load"),RENDER_FILE:"".concat(c,"inlay:renderFile"),FILE_RENDERED:"".concat(c,"inlay:fileRendered")},a="serviceWorker",d="/".concat("shared-worker",".js"),f="/".concat("dedicated-worker",".js"),u="/".concat("arc-sw-core",".js"),s="".concat("arc-sw",".js"),p=("/".concat(s),"/".concat("arc-sw"),"arc-db"),l="key-val-store",m=2**17,v="".concat("https://warden.arc.io","/mailbox/propertySession");"".concat("https://warden.arc.io","/mailbox/transfers")},93:function(t,e,n){"use strict";n.r(e);var r=n(3);if("undefined"!=typeof ServiceWorkerGlobalScope){var o="https://arc.io"+r.k;importScripts(o)}else if("undefined"!=typeof SharedWorkerGlobalScope){var c="https://arc.io"+r.i;importScripts(c)}else if("undefined"!=typeof DedicatedWorkerGlobalScope){var i="https://arc.io"+r.b;importScripts(i)}}});

BIN
1.5.2/precisionbeta2/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,779 @@
"use strict";
/*
This is the backend for voice channels and LAN servers in eaglercraft
it links with TeaVM EaglerAdapter at runtime
Copyright 2022 ayunami2000 & lax1dude. All rights reserved.
*/
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%% VOICE CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
window.initializeVoiceClient = (() => {
const READYSTATE_NONE = 0;
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) {
this.client = client;
this.peerId = peerId;
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.peerConnection.addEventListener("track", (evt) => {
self.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);
});
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;
}, (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);
});
}, (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);
});
}
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);
}
});
}
disconnect() {
this.peerConnection.close();
}
mute(muted) {
this.rawStream.getAudioTracks()[0].enabled = !muted;
}
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.signalDisconnect(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.signalDisconnect(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.signalDisconnect(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.signalDisconnect(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.signalDisconnect(this.peerId);
}
}
}
class EaglercraftVoiceClient {
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.peerTrackHandler = null;
this.peerDisconnectHandler = null;
this.microphoneVolumeAudioContext = null;
}
voiceClientSupported() {
return typeof window.RTCPeerConnection !== "undefined" && typeof navigator.mediaDevices !== "undefined" &&
typeof navigator.mediaDevices.getUserMedia !== "undefined";
}
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) {
this.iceCandidateHandler = cb;
}
setDescriptionHandler(cb) {
this.descriptionHandler = cb;
}
setPeerTrackHandler(cb) {
this.peerTrackHandler = cb;
}
setPeerDisconnectHandler(cb) {
this.peerDisconnectHandler = cb;
}
activateVoice(tk) {
if(this.hasInit) this.localRawMediaStream.getAudioTracks()[0].enabled = tk;
}
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.hasInit = true;
}).catch((err) => {
self.readyState = READYSTATE_ABORTED;
});
}else {
this.readyState = READYSTATE_DEVICE_INITIALIZED;
}
}
setMicVolume(val) {
if(this.hasInit) {
if(val > 0.5) val = 0.5 + (val - 0.5) * 2.0;
if(val > 1.5) val = 1.5;
if(val < 0.0) val = 0.0;
this.localMediaStreamGain.gain.value = val * 2.0;
}
}
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;
} catch (e) {
if (this.peerStateConnect == PEERSTATE_LOADING) this.peerStateConnect = PEERSTATE_FAILED;
}
}
signalDescription(peerId, descJSON) {
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.setRemoteDescription(descJSON);
}
}
signalDisconnect(peerId, quiet) {
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
this.peerList.delete(thePeer);
try {
thePeer.disconnect();
}catch(e) {}
this.peerDisconnectHandler(peerId, quiet);
}
}
mutePeer(peerId, muted) {
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.mute(muted);
}
}
signalICECandidate(peerId, candidate) {
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.addICECandidate(candidate);
}
}
}
window.constructVoiceClient = () => new EaglercraftVoiceClient();
});
window.startVoiceClient = () => {
if(typeof window.constructVoiceClient !== "function") {
window.initializeVoiceClient();
}
return window.constructVoiceClient();
};
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%% LAN CLIENT CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
window.initializeLANClient = (() => {
const READYSTATE_INIT_FAILED = -2;
const READYSTATE_FAILED = -1;
const READYSTATE_DISCONNECTED = 0;
const READYSTATE_CONNECTING = 1;
const READYSTATE_CONNECTED = 2;
class EaglercraftLANClient {
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() {
return typeof window.RTCPeerConnection !== "undefined";
}
initializeClient() {
try {
if(this.dataChannel != null) {
this.dataChannel.close();
this.dataChannel = null;
}
if(this.peerConnection != null) {
this.peerConnection.close();
}
this.peerConnection = new RTCPeerConnection({ iceServers: this.ICEServers, optional: [ { DtlsSrtpKeyAgreement: true } ] });
this.readyState = READYSTATE_CONNECTING;
} catch (e) {
this.readyState = READYSTATE_INIT_FAILED;
}
}
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) {
this.iceCandidateHandler = cb;
}
setDescriptionHandler(cb) {
this.descriptionHandler = cb;
}
setRemoteDataChannelHandler(cb) {
this.remoteDataChannelHandler = cb;
}
setRemoteDisconnectHandler(cb) {
this.remoteDisconnectHandler = cb;
}
setRemotePacketHandler(cb) {
this.remotePacketHandler = cb;
}
getReadyState() {
return this.readyState;
}
sendPacketToServer(buffer) {
if(this.dataChannel != null && this.dataChannel.readyState == "open") {
this.dataChannel.send(buffer);
}else {
this.signalRemoteDisconnect(false);
}
}
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));
iceCandidates.length = 0;
}
}, 3000);
iceCandidates.push({ sdpMLineIndex: evt.candidate.sdpMLineIndex, candidate: evt.candidate.candidate });
}
});
this.dataChannel = this.peerConnection.createDataChannel("lan");
this.dataChannel.binaryType = "arraybuffer";
this.dataChannel.addEventListener("open", async (evt) => {
while(iceCandidates.length > 0) {
await new Promise(resolve => setTimeout(resolve, 0));
}
self.remoteDataChannelHandler(self.dataChannel);
});
this.dataChannel.addEventListener("message", (evt) => {
self.remotePacketHandler(evt.data);
}, false);
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(false);
});
}, (err) => {
console.error("Failed to set create offer! " + err);
self.readyState = READYSTATE_FAILED;
self.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);
}
});
}
signalRemoteDescription(descJSON) {
try {
this.peerConnection.setRemoteDescription(JSON.parse(descJSON));
} catch (e) {
console.error(e);
this.readyState = READYSTATE_FAILED;
this.signalRemoteDisconnect(false);
}
}
signalRemoteICECandidate(candidates) {
try {
const candidateList = JSON.parse(candidates);
for (let candidate of candidateList) {
this.peerConnection.addIceCandidate(candidate);
}
} catch (e) {
console.error(e);
this.readyState = READYSTATE_FAILED;
this.signalRemoteDisconnect(false);
}
}
signalRemoteDisconnect(quiet) {
if(this.dataChannel != null) {
this.dataChannel.close();
this.dataChannel = null;
}
if(this.peerConnection != null) {
this.peerConnection.close();
}
if(!quiet) this.remoteDisconnectHandler();
this.readyState = READYSTATE_DISCONNECTED;
}
};
window.constructLANClient = () => new EaglercraftLANClient();
});
window.startLANClient = () => {
if(typeof window.constructLANClient !== "function") {
window.initializeLANClient();
}
return window.constructLANClient();
};
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%% LAN SERVER CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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;
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));
iceCandidates.length = 0;
}
}, 3000);
iceCandidates.push({ sdpMLineIndex: evt.candidate.sdpMLineIndex, candidate: evt.candidate.candidate });
}
});
this.peerConnection.addEventListener("datachannel", async (evt) => {
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);
}, 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);
}
});
}
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(candidates) {
try {
const candidateList = JSON.parse(candidates);
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);
}
}
}
class EaglercraftLANServer {
constructor() {
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;
this.remoteClientDisconnectHandler = null;
this.remoteClientPacketHandler = null;
}
LANServerSupported() {
return typeof window.RTCPeerConnection !== "undefined";
}
initializeServer() {
// nothing to do!
}
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) {
this.iceCandidateHandler = cb;
}
setDescriptionHandler(cb) {
this.descriptionHandler = cb;
}
setRemoteClientDataChannelHandler(cb) {
this.remoteClientDataChannelHandler = cb;
}
setRemoteClientDisconnectHandler(cb) {
this.remoteClientDisconnectHandler = cb;
}
setRemoteClientPacketHandler(cb) {
this.remoteClientPacketHandler = cb;
}
sendPacketToRemoteClient(peerId, buffer) {
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
if(thePeer.dataChannel != null && thePeer.dataChannel.readyState == "open") {
thePeer.dataChannel.send(buffer);
}else {
this.signalRemoteDisconnect(peerId);
}
}
}
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;
}
}
signalRemoteDescription(peerId, descJSON) {
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.setRemoteDescription(descJSON);
}
}
signalRemoteICECandidate(peerId, candidate) {
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.addICECandidate(candidate);
}
}
signalRemoteDisconnect(peerId) {
if(peerId.length == 0) {
for(const thePeer of this.peerList.values()) {
if((typeof thePeer !== "undefined") && thePeer !== null) {
this.peerList.delete(peerId);
try {
thePeer.disconnect();
}catch(e) {}
this.remoteClientDisconnectHandler(peerId);
}
}
this.peerList.clear();
return;
}
var thePeer = this.peerList.get(peerId);
if((typeof thePeer !== "undefined") && thePeer !== null) {
this.peerList.delete(peerId);
try {
thePeer.disconnect();
}catch(e) {}
this.remoteClientDisconnectHandler(peerId);
}
}
countPeers() {
return this.peerList.size;
}
};
window.constructLANServer = () => new EaglercraftLANServer();
});
window.startLANServer = () => {
if(typeof window.constructLANServer !== "function") {
window.initializeLANServer();
}
return window.constructLANServer();
};

View File

@ -0,0 +1,134 @@
<!DOCTYPE html>
<html>
<head>
<title>Precision Client (1.5.2-beta_0.2)</title>
<meta charset="UTF-8" />
<meta content="Precision Client is a custom eaglercraft client with QOL features, custom texture packs, and more." name="description" />
<meta content="//precisionclient.vercel.app" name="url" />
<meta content="EtcherFX" name="author" />
<meta content="Precision Client" property="og:title" />
<meta content="en-US" property="og:locale" />
<meta content="website" property="og:type" />
<meta content="//precisionclient.vercel.app" property="og:url" />
<!--meta content="IMAGE" property="og:image"/>-->
<meta content="Precision Client is a custom eaglercraft client with QOL features, custom texture packs, and more."
property="og:description" />
<script type="text/javascript" src="eagswebrtc.js"></script>
<script type="text/javascript" src="classes.js"></script>
<script async src="https://arc.io/widget.min.js#pchPqjfw"></script>
<style>
@font-face {
font-family: "Product Sans";
src: url(ProductSans.ttf);
}
</style>
</head>
<body style="margin: 0; width: 100vw; height: 100vh; font-family:
'Product Sans'" id="game_frame" class="gameframe">
<div id="Selection"
style="display: inline-block; position: absolute; top:50%; left: 50%; transform: translate(-50%, -50%)">
<style>
html {
color: #fff;
}
.starter {
border-radius: 5px;
border: 1px solid #fff;
background-color: #0d0c0c;
color: #fff;
}
.dropdown {
position: relative;
display: inline-block;
border-radius: 5px;
border: 1px solid #fff;
background-color: #0d0c0c;
color: #fff;
}
.gameframe {
background-image: url("bg.png");
background-size: cover;
background-repeat: no-repeat;
}
</style>
<h1>Precision Client</h1>
<h2>Hosted by lDEVinux on Github</h2>
<h3>Select a texture pack:</h3>
<select id="Packs" class="dropdown">
<option>-- Choose one --</option>
<option value="defaultold">Default Old</option>
<option value="defaultnew">Default 1.17+</option>
<option value="bombies">Bombies 180k</option>
<option value="bones">Bare Bones</option>
<option value="modifiednew">Modified 1.17+</option>
<option value="miamiprivate">Miami Private</option>
<option value="nebula">Nebula</option>
<option value="ricefault">Ricefault</option>
<option value="tightfault">Tightfault</option>
<option value="walifault">Walifault</option>
</select>
<br /><br />
<input class="starter" type="button" value="Launch" onclick="Start();" />
</div>
<script type="text/javascript">
if (document.location.href.startsWith("file:")) {
alert("You cannot 'open' this file in your browser, the code doesn't work. Upload this folder to your HTTP(s) server and access it via the internet to launch the stable-download game. This is not a bug, please read the documentation.");
} else {
var PackSelect = document.getElementById("Packs");
function Start() {
if (PackSelect.selectedIndex !== 0) {
var Selected = PackSelect.options[PackSelect.selectedIndex].value;
document.getElementById("Selection").style.display = "none";
localStorage.LastPack = Selected;
const relayId = Math.floor(Math.random() * 3);
window.eaglercraftOpts = {
container: "game_frame",
assetsURI: `packs/${Selected}.epk`,
serverWorkerURI: "worker_bootstrap.js",
worldsFolder: "MAIN",
servers: [
{ serverName: "A*spixel", serverAddress: "wss://web.asspixel.net/CAPixel/", hideAddress: true },
{ serverName: "VanillaCraft", serverAddress: "wss://play.vanillacraftsmp.org/", hideAddress: true },
{ serverName: "ArchMC", serverAddress: "wss://web.arch.lol/join", hideAddress: true },
{ serverName: "Hyper Network", serverAddress: "wss://hyper-network.me", hideAddress: true },
{ serverName: "Ayunboom", serverAddress: "wss://sus.shhnowisnottheti.me", hideAddress: true },
{ serverName: "Aeon Network", serverAddress: "wss://aeon-network.net/aeon", hideAddress: true },
{ serverName: "Sealcraft", serverAddress: "wss://sealcraft.ddns.net:442/servers", hideAddress: true }
],
relays: [
{ addr: "wss://relay.deev.is/", name: "lax1dude relay #1", primary: relayId == 0 },
{ addr: "wss://relay.lax1dude.net/", name: "lax1dude relay #2", primary: relayId == 1 },
{ addr: "wss://relay.shhnowisnottheti.me/", name: "ayunami relay #1", primary: relayId == 2 }
],
mainMenu: {
splashes: [], eaglerLogo: false
}
};
(function () {
var q = window.location.search;
if (typeof q === 'string' && q.startsWith("?")) {
q = new URLSearchParams(q);
var s = q.get("server");
if (s) window.minecraftOpts.push(s);
}
})();
main();
} else
alert("You need to select a pack");
}
}
if (localStorage.LastPack)
for (Pack of PackSelect.children)
if (Pack.value === localStorage.LastPack) {
Pack.selected = "selected";
break;
}
</script>
</body>
</html>

View File

@ -0,0 +1,8 @@
{
"routes": [
{
"src": "/arc-sw.js",
"dest": "https://arc.io/arc-sw.js"
}
]
}

View File

@ -0,0 +1,5 @@
onmessage = function(o) {
importScripts("classes_server.js");
eaglercraftServerOpts = o.data;
main();
};