Update to Eaglercraft 1.5 sp2
This commit is contained in:
parent
7a8275c055
commit
9761916953
Binary file not shown.
Binary file not shown.
|
@ -1,4 +1,15 @@
|
|||
|
||||
§lCHANGES §lIN §lSERVICE §lPACK §l#2:§r
|
||||
|
||||
- improved resource packs §4(by §4ayunami2000)§r
|
||||
- improved the FPS even more
|
||||
- improved voice chat reliability
|
||||
- improved shared worlds reliability
|
||||
- backported X's vanilla world export
|
||||
- backported X's vsync mode
|
||||
|
||||
Release date: §912/14/2024§r
|
||||
|
||||
§lCHANGES §lIN §lSERVICE §lPACK §l#1:§r
|
||||
|
||||
- resource packs §4(by §4ayunami2000)§r
|
||||
|
|
|
@ -31,8 +31,8 @@ menu.generatingTerrain=Building terrain
|
|||
menu.convertingLevel=Converting world
|
||||
menu.simulating=Simulating the world for a bit
|
||||
menu.respawning=Respawning
|
||||
menu.shareToLan=Open to LAN
|
||||
menu.closeLan=Close LAN
|
||||
menu.shareToLan=Invite
|
||||
menu.closeLan=Stop Sharing
|
||||
|
||||
menu.skinCapeSettings=Skins/Capes Settings
|
||||
menu.skinCapeSettingsNote0=I put the button up here so
|
||||
|
@ -250,15 +250,15 @@ addServer.enterName=Server Name
|
|||
addServer.enterIp=Server Address
|
||||
addServer.add=Done
|
||||
addServer.hideAddress=Hide Address
|
||||
lanServer.title=LAN World
|
||||
lanServer.title=Shared World
|
||||
lanServer.scanning=Scanning for games on your local network
|
||||
lanServer.start=Start LAN World
|
||||
lanServer.start=Start Shared World
|
||||
lanServer.otherPlayers=Settings for Other Players
|
||||
mcoServer.title=yeeeeeee
|
||||
addServer.SSLWarn1=you are on an https: page!
|
||||
addServer.SSLWarn2=html5 will only allow wss://
|
||||
directConnect.prompt=What would you like to do?
|
||||
directConnect.lanWorld=Join LAN World
|
||||
directConnect.lanWorld=Join Shared World
|
||||
directConnect.lanWorldCode=Enter Join Code:
|
||||
directConnect.networkSettingsNote=Click 'Network Settings' to add a relay URL
|
||||
directConnect.ipGrabNote=Note: The world's owner can get your IP address
|
||||
|
@ -266,7 +266,7 @@ directConnect.serverJoin=Connect to Server
|
|||
directConnect.lanWorldJoin=Join World
|
||||
directConnect.lanWorldRelay=Network Settings
|
||||
|
||||
lanServer.pauseMenu0=Sharing to LAN
|
||||
lanServer.pauseMenu0=Sharing World
|
||||
lanServer.pauseMenu1=Relay URL:
|
||||
lanServer.pauseMenu2=Join Code:
|
||||
|
||||
|
@ -276,13 +276,13 @@ lanServer.worldName=World Name:
|
|||
lanServer.hidden=Hidden:
|
||||
lanServer.hideCode=hide details
|
||||
lanServer.showCode=show details
|
||||
lanServer.opened=LAN world opened on $relay$, join code is §a$code$
|
||||
lanServer.closed=LAN world closed
|
||||
lanServer.opened=Shared world opened on $relay$, join code is §a$code$
|
||||
lanServer.closed=Shared world closed
|
||||
lanServer.pleaseWait=Please Wait...
|
||||
lanServer.relayDisconnected=Error: connection to LAN relay was lost, you must re-share the world to invide more people
|
||||
lanServer.relayDisconnected=Error: connection to shared world relay was lost, you must re-share the world to invide more people
|
||||
lanServer.ipGrabNote=Note: Players joining your world can get your IP address
|
||||
|
||||
networkSettings.title=LAN World Relay Servers
|
||||
networkSettings.title=Shared World Relay Servers
|
||||
networkSettings.add=Add Relay
|
||||
networkSettings.delete=Delete Relay
|
||||
networkSettings.default=Set Primary
|
||||
|
@ -492,6 +492,18 @@ performance.max=Max FPS
|
|||
performance.balanced=Balanced
|
||||
performance.powersaver=Power saver
|
||||
|
||||
options.vsyncWarning.title=Issues Detected
|
||||
options.vsyncWarning.0=Some of your video settings may be causing
|
||||
options.vsyncWarning.1=the game to lag excessively
|
||||
options.vsyncWarning.2=VSync is disabled, some browsers require
|
||||
options.vsyncWarning.3=VSync to be enabled to hint when the
|
||||
options.vsyncWarning.4=framebuffer has updated. If the game feels
|
||||
options.vsyncWarning.5=significantly slower than is indicated by
|
||||
options.vsyncWarning.6=the FPS counter, you should enable VSync.
|
||||
options.vsyncWarning.fixSettings=Fix Settings
|
||||
options.vsyncWarning.continueAnyway=Continue Anyway
|
||||
options.vsyncWarning.doNotShowAgain=Do Not Show Again
|
||||
|
||||
controls.title=Controls
|
||||
|
||||
key.forward=Forward
|
||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -1,33 +1,30 @@
|
|||
|
||||
# Eaglercraft 1.5.2 - Service Pack 1
|
||||
# Eaglercraft 1.5.2 - Service Pack 2
|
||||
|
||||
### Released: October 27th, 2023 - "23w43a"
|
||||
###
|
||||
### Released: December 14th, 2024 - "24w50a"
|
||||
|
||||
![eaglercraft](https://g.deev.is/eaglercraft/cover.png)
|
||||
:-:
|
||||
Eaglercraft is real Minecraft 1.5.2 that you can play in any regular web browser. That includes school chromebooks, it works on all chromebooks. It supports both singleplayer and multiplayer.
|
||||
|
||||
# New in Service Pack 1:
|
||||
**Huge FPS boosts, lessons learned during the development of EaglercraftX 1.8 have been applied to 1.5, and [ayunami2000](https://github.com/ayunami2000/) added basic support for resource packs. Update your unblocked game websites ASAP for the best user experience on slow hardware.**
|
||||
- fixed sunrise/sunset fog color
|
||||
- better optimized pipeline shader
|
||||
- backported X's state management
|
||||
- backported X's buffer streaming
|
||||
- backported X's hotbar FPS fix
|
||||
- backported X's double buffering
|
||||
- backported X's FXAA shader
|
||||
# New in Service Pack 2:
|
||||
- improved resource packs (by ayunami2000)
|
||||
- improved the FPS even more
|
||||
- improved voice chat reliability
|
||||
- improved shared worlds reliability
|
||||
- backported X's vanilla world export
|
||||
- backported X's vsync mode
|
||||
|
||||
**The LAN world relay server is now bundled with the client, you can download it using a button in the "Network Settings" menu where LAN relays are configured. Hopefully this will prevent LAN worlds from ever becoming defunct once our default relay servers no longer exist.**
|
||||
**The updated shared world relay server is bundled with the client, you can download it using a button in the "Network Settings" menu where shared world relays are configured. Hopefully this will prevent shared worlds from ever becoming defunct once our default relay servers no longer exist.**
|
||||
|
||||
|
||||
# Table Of Contents:
|
||||
| [Singleplayer](#Singleplayer) | [Multiplayer](#Multiplayer) | [Others](#Others) |
|
||||
|---------------------------------------------------------------|---------------------------------------------------------------------------------|-------------------------------------------------------|
|
||||
| [Importing and Exporting Worlds](#Importing-and-Exporting-Worlds) | [Public clients and servers](#Public-clients-and-servers) | [Plugin Development](#Plugin-Development) |
|
||||
| [LAN Worlds](#LAN-Worlds) | [Creating a Server - Bukkit](#Creating-a-server---Bukkit) | [Compiling](#Compiling) |
|
||||
| [Public LAN Relays](#Public-LAN-Relays) | [Creating a Server - EaglercraftBungee](#Creating-a-server---EaglercraftBungee) | [Creating a resource pack](#Creating-a-resource-pack) |
|
||||
| [Creating a LAN Relay](#Creating-a-LAN-Relay) | [Creating a Client](#Creating-a-Client) | [Contributing](#Contributing) |
|
||||
| [Importing and Exporting Worlds](#Importing-and-Exporting-Worlds) | [Public clients and servers](#Public-clients-and-servers) | [Plugin Development](#Plugin-Development) |
|
||||
| [Shared Worlds](#Shared-Worlds) | [Creating a Server - Bukkit](#Creating-a-server---Bukkit) | [Compiling](#Compiling) |
|
||||
| [Public Shared World Relays](#Public-Shared-World-Relays) | [Creating a Server - EaglercraftBungee](#Creating-a-server---EaglercraftBungee) | [Creating a resource pack](#Creating-a-resource-pack) |
|
||||
| [Creating a Shared World Relay](#Creating-a-Shared-World-Relay) | [Creating a Client](#Creating-a-Client) | [Contributing](#Contributing) |
|
||||
| | [EaglercraftBungee Configuration](#EaglercraftBungee-Configuration) | |
|
||||
| | [Creating a Reverse Proxy - NGINX](#Creating-a-Reverse-Proxy---NGINX) | |
|
||||
| | [NGINX Configuration](#NGINX-Configuration) | |
|
||||
|
@ -39,21 +36,21 @@ Simply press the 'Singleplayer' button on the main menu and you can create a reg
|
|||
## Importing and Exporting Worlds
|
||||
The worlds are stored in your browser's local storage, **you can export them as EPK files and import them again on all other Eaglercraft sites that also support singleplayer.** You can even copy an exported world to an entirely different computer, or send it to a friend, and import it and continue playing with all your progress saved.
|
||||
|
||||
## LAN Worlds
|
||||
## Shared Worlds
|
||||
|
||||
### Eaglercraft fully supports LAN worlds, you can share your world with any player and they can connect directly to it as if you are running a server in your browser.
|
||||
### Eaglercraft fully supports shared worlds, you can share your world with any player and they can connect directly to it as if you are running a server in your browser.
|
||||
|
||||
**LAN worlds will work between any two devices connected to the internet, you are not limited to only players connected to your Wi-Fi network**
|
||||
### This feature was originally called "LAN Worlds" but has been renamed to "Shared Worlds" to avoid confusing people who believed it only works if both devices are on the same Wi-Fi network
|
||||
|
||||
To open your world to LAN, go to the pause menu and click 'Open to LAN'. You can configure the gamemode and cheats and if you would like to hide your LAN world. **When you do not hide your LAN world, it will appear on the Multiplayer screen from the main menu to anybody else also on your Wi-Fi network.** Set the world hidden if you are at school or something and don't want everyone else in your class to join as well and start griefing.
|
||||
To invite players to your world, go to the pause menu and click 'Invite'. You can configure the gamemode and cheats and if you would like to hide your world from others. **When you do not hide your shared world, it will appear on the Multiplayer screen from the main menu to anybody else also on your Wi-Fi network.** Set the world hidden if you are at school or something and don't want everyone else in your class to join as well and start griefing.
|
||||
|
||||
When you open the world to LAN it will give you a 'join code'. Simply share the code with your friends and they can visit the Multiplayer screen from the main menu and click 'Direct Connect' and enter the code and they will be able to join your world.
|
||||
When you share the world it will give you a 'join code'. Simply share the code with your friends and they can visit the Multiplayer screen from the main menu and click 'Direct Connect' and enter the code and they will be able to join your world.
|
||||
|
||||
Make sure they add the relay server your game opens the LAN world on to their "Network Settings" menu accessable from the Multiplayer screen. You simply must send them the URL indicated in the pause menu once the world is opened and they can use the "Add Relay" option to add the URL to their list.
|
||||
Make sure they add the relay server your game opens the shred world on to their "Network Settings" menu accessable from the Multiplayer screen. You simply must send them the URL indicated in the pause menu once the world is opened and they can use the "Add Relay" option to add the URL to their list.
|
||||
|
||||
### THIS IS A REQUIRED STEP FOR A PERSON TO JOIN YOUR WORLD, IF THEY DO NOT HAVE THE RELAY YOUR WORLD IS HOSTED ON ADDED TO THEIR "Network Settings" THE GAME WILL BE UNABLE TO LOCATE THE WORLD
|
||||
|
||||
## Public LAN Relays
|
||||
## Public Shared World Relays
|
||||
|
||||
### Here are some public relay servers you can use:
|
||||
|
||||
|
@ -61,13 +58,13 @@ Make sure they add the relay server your game opens the LAN world on to their "N
|
|||
- `wss://relay.lax1dude.net/`
|
||||
- `wss://relay.shhnowisnottheti.me/`
|
||||
|
||||
## Creating a LAN Relay
|
||||
## Creating a Shared World Relay
|
||||
|
||||
### Simply download [stable-download/sp-relay.jar](https://github.com/lax1dude/eaglercraft/blob/main/stable-download/sp-relay.jar) and run `java -jar sp-relay.jar`
|
||||
### The source code of the shared world relay has been moved to the EaglercraftX repository, however a copy of the compiled JAR file is embedded in every client and can be downloaded from the "Network Settings" screen.
|
||||
|
||||
**Run `java -jar sp-relay.jar --debug` to view debug info like all the IPs of incoming connections, as it is not shown by default because logging all that info will reduce performance when the relay is being pinged many times a second depending on it's popularity.**
|
||||
**Run `java -jar EaglerSPRelay.jar --debug` to view debug info like all the IPs of incoming connections, as it is not shown by default because logging all that info will reduce performance when the relay is being pinged many times a second depending on it's popularity.**
|
||||
|
||||
Edit the `relayConfig.ini` file generated on first launch to change the port and configure ratelimiting and such, and `relays.txt` to change the list of STUN and TURN relays reported to clients connecting to the relay, which are required to correctly establish a P2P LAN world connection in browsers
|
||||
Edit the `relayConfig.ini` file generated on first launch to change the port and configure ratelimiting and such, and `relays.txt` to change the list of STUN and TURN relays reported to clients connecting to the relay, which are required to correctly establish a P2P connection in browsers
|
||||
|
||||
**The `origin-whitelist` config variable is a semicolon (`;`) seperated list of domains used to restrict what sites are to be allowed to use your relay. When left blank it allows all sites. Add `offline` to allow offline download clients to use your relay as well, and `null` to allow connections that do not specify an `Origin:` header. Use `*` as a wildcard, for example: `*.deev.is` allows all domains ending with "deev.is" to use the relay.**
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
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
|
@ -1,29 +1,26 @@
|
|||
window.initializeVoiceClient=()=>{class k{constructor(a,b,c,f){this.client=a;this.peerId=b;this.peerConnection=c;this.stream=null;const e=this;this.peerConnection.addEventListener("icecandidate",g=>{g.candidate&&e.client.iceCandidateHandler(e.peerId,JSON.stringify({sdpMLineIndex:g.candidate.sdpMLineIndex,candidate:g.candidate.candidate}))});this.peerConnection.addEventListener("track",g=>{e.rawStream=g.streams[0];const h=new Audio;h.autoplay=!0;h.muted=!0;h.onended=function(){h.remove()};h.srcObject=
|
||||
e.rawStream;e.client.peerTrackHandler(e.peerId,e.rawStream)});this.peerConnection.addStream(this.client.localMediaStream.stream);f&&this.peerConnection.createOffer(g=>{e.peerConnection.setLocalDescription(g,()=>{e.client.descriptionHandler(e.peerId,JSON.stringify(g));1!=e.client.peerStateInitial&&(e.client.peerStateInitial=1)},h=>{console.error('Failed to set local description for "'+e.peerId+'"! '+h);2==e.client.peerStateInitial&&(e.client.peerStateInitial=0);e.client.signalDisconnect(e.peerId)})},
|
||||
g=>{console.error('Failed to set create offer for "'+e.peerId+'"! '+g);2==e.client.peerStateInitial&&(e.client.peerStateInitial=0);e.client.signalDisconnect(e.peerId)});this.peerConnection.addEventListener("connectionstatechange",g=>{"disconnected"===e.peerConnection.connectionState?e.client.signalDisconnect(e.peerId):"connected"===e.peerConnection.connectionState?1!=e.client.peerState&&(e.client.peerState=1):"failed"===e.peerConnection.connectionState&&(2==e.client.peerState&&(e.client.peerState=
|
||||
0),e.client.signalDisconnect(e.peerId))})}disconnect(){this.peerConnection.close()}mute(a){this.rawStream.getAudioTracks()[0].enabled=!a}setRemoteDescription(a){const b=this;try{const c=JSON.parse(a);this.peerConnection.setRemoteDescription(c,()=>{"offer"==c.type&&b.peerConnection.createAnswer(f=>{b.peerConnection.setLocalDescription(f,()=>{b.client.descriptionHandler(b.peerId,JSON.stringify(f));1!=b.client.peerStateDesc&&(b.client.peerStateDesc=1)},e=>{console.error('Failed to set local description for "'+
|
||||
b.peerId+'"! '+e);2==b.client.peerStateDesc&&(b.client.peerStateDesc=0);b.client.signalDisconnect(b.peerId)})},f=>{console.error('Failed to create answer for "'+b.peerId+'"! '+f);2==b.client.peerStateDesc&&(b.client.peerStateDesc=0);b.client.signalDisconnect(b.peerId)})},f=>{console.error('Failed to set remote description for "'+b.peerId+'"! '+f);2==b.client.peerStateDesc&&(b.client.peerStateDesc=0);b.client.signalDisconnect(b.peerId)})}catch(c){console.error('Failed to parse remote description for "'+
|
||||
b.peerId+'"! '+c),2==b.client.peerStateDesc&&(b.client.peerStateDesc=0),b.client.signalDisconnect(b.peerId)}}addICECandidate(a){try{this.peerConnection.addIceCandidate(new RTCIceCandidate(JSON.parse(a))),1!=this.client.peerStateIce&&(this.client.peerStateIce=1)}catch(b){console.error('Failed to parse ice candidate for "'+this.peerId+'"! '+b),2==this.client.peerStateIce&&(this.client.peerStateIce=0),this.client.signalDisconnect(this.peerId)}}}class d{constructor(){this.ICEServers=[];this.hasInit=!1;
|
||||
this.peerList=new Map;this.readyState=0;this.peerStateIce=this.peerStateDesc=this.peerStateInitial=this.peerStateConnect=this.peerState=2;this.microphoneVolumeAudioContext=this.peerDisconnectHandler=this.peerTrackHandler=this.descriptionHandler=this.iceCandidateHandler=null}voiceClientSupported(){return"undefined"!==typeof window.RTCPeerConnection&&"undefined"!==typeof navigator.mediaDevices&&"undefined"!==typeof navigator.mediaDevices.getUserMedia}setICEServers(a){for(var b=this.ICEServers.length=
|
||||
0;b<a.length;++b){var c=a[b].split(";");1==c.length?this.ICEServers.push({urls:c[0]}):3==c.length&&this.ICEServers.push({urls:c[0],username:c[1],credential:c[2]})}}setICECandidateHandler(a){this.iceCandidateHandler=a}setDescriptionHandler(a){this.descriptionHandler=a}setPeerTrackHandler(a){this.peerTrackHandler=a}setPeerDisconnectHandler(a){this.peerDisconnectHandler=a}activateVoice(a){this.hasInit&&(this.localRawMediaStream.getAudioTracks()[0].enabled=a)}initializeDevices(){if(this.hasInit)this.readyState=
|
||||
1;else{const a=this;navigator.mediaDevices.getUserMedia({audio:!0,video:!1}).then(b=>{a.microphoneVolumeAudioContext=new AudioContext;a.localRawMediaStream=b;a.localRawMediaStream.getAudioTracks()[0].enabled=!1;a.localMediaStream=a.microphoneVolumeAudioContext.createMediaStreamDestination();a.localMediaStreamGain=a.microphoneVolumeAudioContext.createGain();a.microphoneVolumeAudioContext.createMediaStreamSource(b).connect(a.localMediaStreamGain);a.localMediaStreamGain.connect(a.localMediaStream);a.localMediaStreamGain.gain.value=
|
||||
1;a.readyState=1;this.hasInit=!0}).catch(b=>{a.readyState=-1})}}setMicVolume(a){this.hasInit&&(.5<a&&(a=.5+2*(a-.5)),1.5<a&&(a=1.5),0>a&&(a=0),this.localMediaStreamGain.gain.value=2*a)}resetPeerStates(){this.peerState=this.peerStateConnect=this.peerStateInitial=this.peerStateDesc=this.peerStateIce=2}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(a,
|
||||
b){this.hasInit||this.initializeDevices();try{const c=new RTCPeerConnection({iceServers:this.ICEServers,optional:[{DtlsSrtpKeyAgreement:!0}]}),f=new k(this,a,c,b);this.peerList.set(a,f);1!=this.peerStateConnect&&(this.peerStateConnect=1)}catch(c){2==this.peerStateConnect&&(this.peerStateConnect=0)}}signalDescription(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.setRemoteDescription(b)}signalDisconnect(a,b){var c=this.peerList.get(a);if("undefined"!==typeof c&&null!==c){this.peerList.delete(c);
|
||||
try{c.disconnect()}catch(f){}this.peerDisconnectHandler(a,b)}}mutePeer(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.mute(b)}signalICECandidate(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.addICECandidate(b)}}window.constructVoiceClient=()=>new d};window.startVoiceClient=()=>{"function"!==typeof window.constructVoiceClient&&window.initializeVoiceClient();return window.constructVoiceClient()};
|
||||
window.initializeLANClient=()=>{class k{constructor(){this.ICEServers=[];this.dataChannel=this.peerConnection=null;this.readyState=1;this.remotePacketHandler=this.remoteDisconnectHandler=this.remoteDataChannelHandler=this.descriptionHandler=this.iceCandidateHandler=null}LANClientSupported(){return"undefined"!==typeof window.RTCPeerConnection}initializeClient(){try{null!=this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null),null!=this.peerConnection&&this.peerConnection.close(),this.peerConnection=
|
||||
new RTCPeerConnection({iceServers:this.ICEServers,optional:[{DtlsSrtpKeyAgreement:!0}]}),this.readyState=1}catch(d){this.readyState=-2}}setICEServers(d){for(var a=this.ICEServers.length=0;a<d.length;++a){var b=d[a].split(";");1==b.length?this.ICEServers.push({urls:b[0]}):3==b.length&&this.ICEServers.push({urls:b[0],username:b[1],credential:b[2]})}}setICECandidateHandler(d){this.iceCandidateHandler=d}setDescriptionHandler(d){this.descriptionHandler=d}setRemoteDataChannelHandler(d){this.remoteDataChannelHandler=
|
||||
d}setRemoteDisconnectHandler(d){this.remoteDisconnectHandler=d}setRemotePacketHandler(d){this.remotePacketHandler=d}getReadyState(){return this.readyState}sendPacketToServer(d){null!=this.dataChannel&&"open"==this.dataChannel.readyState?this.dataChannel.send(d):this.signalRemoteDisconnect(!1)}signalRemoteConnect(){const d=this,a=[];this.peerConnection.addEventListener("icecandidate",b=>{b.candidate&&(0==a.length&&setTimeout(()=>{null!=d.peerConnection&&"disconnected"!=d.peerConnection.connectionState&&
|
||||
(d.iceCandidateHandler(JSON.stringify(a)),a.length=0)},3E3),a.push({sdpMLineIndex:b.candidate.sdpMLineIndex,candidate:b.candidate.candidate}))});this.dataChannel=this.peerConnection.createDataChannel("lan");this.dataChannel.binaryType="arraybuffer";this.dataChannel.addEventListener("open",async b=>{for(;0<a.length;)await new Promise(c=>setTimeout(c,0));d.remoteDataChannelHandler(d.dataChannel)});this.dataChannel.addEventListener("message",b=>{d.remotePacketHandler(b.data)},!1);this.peerConnection.createOffer(b=>
|
||||
{d.peerConnection.setLocalDescription(b,()=>{d.descriptionHandler(JSON.stringify(b))},c=>{console.error("Failed to set local description! "+c);d.readyState=-1;d.signalRemoteDisconnect(!1)})},b=>{console.error("Failed to set create offer! "+b);d.readyState=-1;d.signalRemoteDisconnect(!1)});this.peerConnection.addEventListener("connectionstatechange",b=>{"disconnected"===d.peerConnection.connectionState?d.signalRemoteDisconnect(!1):"connected"===d.peerConnection.connectionState?d.readyState=2:"failed"===
|
||||
d.peerConnection.connectionState&&(d.readyState=-1,d.signalRemoteDisconnect(!1))})}signalRemoteDescription(d){try{this.peerConnection.setRemoteDescription(JSON.parse(d))}catch(a){console.error(a),this.readyState=-1,this.signalRemoteDisconnect(!1)}}signalRemoteICECandidate(d){try{const a=JSON.parse(d);for(let b of a)this.peerConnection.addIceCandidate(b)}catch(a){console.error(a),this.readyState=-1,this.signalRemoteDisconnect(!1)}}signalRemoteDisconnect(d){null!=this.dataChannel&&(this.dataChannel.close(),
|
||||
this.dataChannel=null);null!=this.peerConnection&&this.peerConnection.close();d||this.remoteDisconnectHandler();this.readyState=0}}window.constructLANClient=()=>new k};window.startLANClient=()=>{"function"!==typeof window.constructLANClient&&window.initializeLANClient();return window.constructLANClient()};
|
||||
window.initializeLANServer=()=>{class k{constructor(a,b,c){this.client=a;this.peerId=b;this.peerConnection=c;this.dataChannel=null;const f=this,e=[];this.peerConnection.addEventListener("icecandidate",g=>{g.candidate&&(0==e.length&&setTimeout(()=>{null!=f.peerConnection&&"disconnected"!=f.peerConnection.connectionState&&(f.client.iceCandidateHandler(f.peerId,JSON.stringify(e)),e.length=0)},3E3),e.push({sdpMLineIndex:g.candidate.sdpMLineIndex,candidate:g.candidate.candidate}))});this.peerConnection.addEventListener("datachannel",
|
||||
async g=>{for(;0<e.length;)await new Promise(h=>setTimeout(h,0));f.dataChannel=g.channel;f.client.remoteClientDataChannelHandler(f.peerId,f.dataChannel);f.dataChannel.addEventListener("message",h=>{f.client.remoteClientPacketHandler(f.peerId,h.data)},!1)},!1);this.peerConnection.addEventListener("connectionstatechange",g=>{"disconnected"===f.peerConnection.connectionState?f.client.signalRemoteDisconnect(f.peerId):"connected"===f.peerConnection.connectionState?1!=f.client.peerState&&(f.client.peerState=
|
||||
1):"failed"===f.peerConnection.connectionState&&(2==f.client.peerState&&(f.client.peerState=0),f.client.signalRemoteDisconnect(f.peerId))})}disconnect(){null!=this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null);this.peerConnection.close()}setRemoteDescription(a){const b=this;try{const c=JSON.parse(a);this.peerConnection.setRemoteDescription(c,()=>{"offer"==c.type&&b.peerConnection.createAnswer(f=>{b.peerConnection.setLocalDescription(f,()=>{b.client.descriptionHandler(b.peerId,JSON.stringify(f));
|
||||
1!=b.client.peerStateDesc&&(b.client.peerStateDesc=1)},e=>{console.error('Failed to set local description for "'+b.peerId+'"! '+e);2==b.client.peerStateDesc&&(b.client.peerStateDesc=0);b.client.signalRemoteDisconnect(b.peerId)})},f=>{console.error('Failed to create answer for "'+b.peerId+'"! '+f);2==b.client.peerStateDesc&&(b.client.peerStateDesc=0);b.client.signalRemoteDisconnect(b.peerId)})},f=>{console.error('Failed to set remote description for "'+b.peerId+'"! '+f);2==b.client.peerStateDesc&&
|
||||
(b.client.peerStateDesc=0);b.client.signalRemoteDisconnect(b.peerId)})}catch(c){console.error('Failed to parse remote description for "'+b.peerId+'"! '+c),2==b.client.peerStateDesc&&(b.client.peerStateDesc=0),b.client.signalRemoteDisconnect(b.peerId)}}addICECandidate(a){try{const b=JSON.parse(a);for(let c of b)this.peerConnection.addIceCandidate(new RTCIceCandidate(c));1!=this.client.peerStateIce&&(this.client.peerStateIce=1)}catch(b){console.error('Failed to parse ice candidate for "'+this.peerId+
|
||||
'"! '+b),2==this.client.peerStateIce&&(this.client.peerStateIce=0),this.client.signalRemoteDisconnect(this.peerId)}}}class d{constructor(){this.ICEServers=[];this.hasInit=!1;this.peerList=new Map;this.peerStateIce=this.peerStateDesc=this.peerStateInitial=this.peerStateConnect=this.peerState=2;this.remoteClientPacketHandler=this.remoteClientDisconnectHandler=this.remoteClientDataChannelHandler=this.descriptionHandler=this.iceCandidateHandler=null}LANServerSupported(){return"undefined"!==typeof window.RTCPeerConnection}initializeServer(){}setICEServers(a){for(var b=
|
||||
this.ICEServers.length=0;b<a.length;++b){var c=a[b].split(";");1==c.length?this.ICEServers.push({urls:c[0]}):3==c.length&&this.ICEServers.push({urls:c[0],username:c[1],credential:c[2]})}}setICECandidateHandler(a){this.iceCandidateHandler=a}setDescriptionHandler(a){this.descriptionHandler=a}setRemoteClientDataChannelHandler(a){this.remoteClientDataChannelHandler=a}setRemoteClientDisconnectHandler(a){this.remoteClientDisconnectHandler=a}setRemoteClientPacketHandler(a){this.remoteClientPacketHandler=
|
||||
a}sendPacketToRemoteClient(a,b){var c=this.peerList.get(a);"undefined"!==typeof c&&null!==c&&(null!=c.dataChannel&&"open"==c.dataChannel.readyState?c.dataChannel.send(b):this.signalRemoteDisconnect(a))}resetPeerStates(){this.peerState=this.peerStateConnect=this.peerStateInitial=this.peerStateDesc=this.peerStateIce=2}getPeerState(){return this.peerState}getPeerStateConnect(){return this.peerStateConnect}getPeerStateInitial(){return this.peerStateInitial}getPeerStateDesc(){return this.peerStateDesc}getPeerStateIce(){return this.peerStateIce}signalRemoteConnect(a){try{const b=
|
||||
new RTCPeerConnection({iceServers:this.ICEServers,optional:[{DtlsSrtpKeyAgreement:!0}]}),c=new k(this,a,b);this.peerList.set(a,c);1!=this.peerStateConnect&&(this.peerStateConnect=1)}catch(b){2==this.peerStateConnect&&(this.peerStateConnect=0)}}signalRemoteDescription(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.setRemoteDescription(b)}signalRemoteICECandidate(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.addICECandidate(b)}signalRemoteDisconnect(a){if(0==a.length){for(var b of this.peerList.values())if("undefined"!==
|
||||
typeof b&&null!==b){this.peerList.delete(a);try{b.disconnect()}catch(c){}this.remoteClientDisconnectHandler(a)}this.peerList.clear()}else if(b=this.peerList.get(a),"undefined"!==typeof b&&null!==b){this.peerList.delete(a);try{b.disconnect()}catch(c){}this.remoteClientDisconnectHandler(a)}}countPeers(){return this.peerList.size}}window.constructLANServer=()=>new d};window.startLANServer=()=>{"function"!==typeof window.constructLANServer&&window.initializeLANServer();return window.constructLANServer()};
|
||||
window.initializeVoiceClient=()=>{class k{constructor(a,b,c,e){this.client=a;this.peerId=b;this.peerConnection=c;this.stream=null;this.peerConnection.addEventListener("icecandidate",f=>{f.candidate&&this.client.iceCandidateHandler(this.peerId,JSON.stringify({sdpMLineIndex:f.candidate.sdpMLineIndex,candidate:f.candidate.candidate}))});this.peerConnection.addEventListener("track",f=>{this.rawStream=f.streams[0];const g=new Audio;g.autoplay=!0;g.muted=!0;g.onended=function(){g.remove()};g.srcObject=
|
||||
this.rawStream;this.client.peerTrackHandler(this.peerId,this.rawStream)});this.peerConnection.addStream(this.client.localMediaStream.stream);e&&this.peerConnection.createOffer(f=>{this.peerConnection.setLocalDescription(f,()=>{this.client.descriptionHandler(this.peerId,JSON.stringify(f))},g=>{console.error('Failed to set local description for "'+this.peerId+'"! '+g);this.client.signalDisconnect(this.peerId)})},f=>{console.error('Failed to set create offer for "'+this.peerId+'"! '+f);this.client.signalDisconnect(this.peerId)});
|
||||
this.peerConnection.addEventListener("connectionstatechange",f=>{"disconnected"!==this.peerConnection.connectionState&&"failed"!==this.peerConnection.connectionState||this.client.signalDisconnect(this.peerId)})}disconnect(){this.peerConnection.close()}mute(a){this.rawStream.getAudioTracks()[0].enabled=!a}setRemoteDescription(a){try{const b=JSON.parse(a);this.peerConnection.setRemoteDescription(b,()=>{"offer"===b.type&&this.peerConnection.createAnswer(c=>{this.peerConnection.setLocalDescription(c,
|
||||
()=>{this.client.descriptionHandler(this.peerId,JSON.stringify(c))},e=>{console.error('Failed to set local description for "'+this.peerId+'"! '+e);this.client.signalDisconnect(this.peerId)})},c=>{console.error('Failed to create answer for "'+this.peerId+'"! '+c);this.client.signalDisconnect(this.peerId)})},c=>{console.error('Failed to set remote description for "'+this.peerId+'"! '+c);this.client.signalDisconnect(this.peerId)})}catch(b){console.error('Failed to parse remote description for "'+this.peerId+
|
||||
'"! '+b),this.client.signalDisconnect(this.peerId)}}addICECandidate(a){try{this.peerConnection.addIceCandidate(new RTCIceCandidate(JSON.parse(a)))}catch(b){console.error('Failed to parse ice candidate for "'+this.peerId+'"! '+b),this.client.signalDisconnect(this.peerId)}}}class d{constructor(){this.ICEServers=[];this.hasInit=!1;this.peerList=new Map;this.readyState=0;this.microphoneVolumeAudioContext=this.peerDisconnectHandler=this.peerTrackHandler=this.descriptionHandler=this.iceCandidateHandler=
|
||||
null}voiceClientSupported(){return"undefined"!==typeof window.RTCPeerConnection&&"undefined"!==typeof navigator.mediaDevices&&"undefined"!==typeof navigator.mediaDevices.getUserMedia}setICEServers(a){for(var b=this.ICEServers.length=0;b<a.length;++b){var c=a[b].split(";");1===c.length?this.ICEServers.push({urls:c[0]}):3===c.length&&this.ICEServers.push({urls:c[0],username:c[1],credential:c[2]})}}setICECandidateHandler(a){this.iceCandidateHandler=a}setDescriptionHandler(a){this.descriptionHandler=
|
||||
a}setPeerTrackHandler(a){this.peerTrackHandler=a}setPeerDisconnectHandler(a){this.peerDisconnectHandler=a}activateVoice(a){this.hasInit&&(this.localRawMediaStream.getAudioTracks()[0].enabled=a)}initializeDevices(){this.hasInit?this.readyState=1:navigator.mediaDevices.getUserMedia({audio:!0,video:!1}).then(a=>{this.microphoneVolumeAudioContext=new AudioContext;this.localRawMediaStream=a;this.localRawMediaStream.getAudioTracks()[0].enabled=!1;this.localMediaStream=this.microphoneVolumeAudioContext.createMediaStreamDestination();
|
||||
this.localMediaStreamGain=this.microphoneVolumeAudioContext.createGain();this.microphoneVolumeAudioContext.createMediaStreamSource(a).connect(this.localMediaStreamGain);this.localMediaStreamGain.connect(this.localMediaStream);this.readyState=this.localMediaStreamGain.gain.value=1;this.hasInit=!0}).catch(a=>{this.readyState=-1})}setMicVolume(a){this.hasInit&&(.5<a&&(a=.5+2*(a-.5)),1.5<a&&(a=1.5),0>a&&(a=0),this.localMediaStreamGain.gain.value=2*a)}getReadyState(){return this.readyState}signalConnect(a,
|
||||
b){try{const c=new RTCPeerConnection({iceServers:this.ICEServers,optional:[{DtlsSrtpKeyAgreement:!0}]}),e=new k(this,a,c,b);this.peerList.set(a,e)}catch(c){}}signalDescription(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.setRemoteDescription(b)}signalDisconnect(a,b){var c=this.peerList.get(a);if("undefined"!==typeof c&&null!==c){this.peerList.delete(c);try{c.disconnect()}catch(e){}this.peerDisconnectHandler(a,b)}}mutePeer(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==
|
||||
a&&a.mute(b)}signalICECandidate(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.addICECandidate(b)}}window.constructVoiceClient=()=>new d};window.startVoiceClient=()=>{"function"!==typeof window.constructVoiceClient&&window.initializeVoiceClient();return window.constructVoiceClient()};
|
||||
window.initializeLANClient=()=>{class k{constructor(){this.ICEServers=[];this.dataChannel=this.peerConnection=null;this.readyState=1;this.remotePacketHandler=this.remoteDisconnectHandler=this.remoteDataChannelHandler=this.descriptionHandler=this.iceCandidateHandler=null}LANClientSupported(){return"undefined"!==typeof window.RTCPeerConnection}initializeClient(){try{null!==this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null),null!==this.peerConnection&&this.peerConnection.close(),this.peerConnection=
|
||||
new RTCPeerConnection({iceServers:this.ICEServers,optional:[{DtlsSrtpKeyAgreement:!0}]}),this.readyState=1}catch(d){this.readyState=-2}}setICEServers(d){for(var a=this.ICEServers.length=0;a<d.length;++a){var b=d[a].split(";");1===b.length?this.ICEServers.push({urls:b[0]}):3===b.length&&this.ICEServers.push({urls:b[0],username:b[1],credential:b[2]})}}setICECandidateHandler(d){this.iceCandidateHandler=d}setDescriptionHandler(d){this.descriptionHandler=d}setRemoteDataChannelHandler(d){this.remoteDataChannelHandler=
|
||||
d}setRemoteDisconnectHandler(d){this.remoteDisconnectHandler=d}setRemotePacketHandler(d){this.remotePacketHandler=d}getReadyState(){return this.readyState}sendPacketToServer(d){null!==this.dataChannel&&"open"===this.dataChannel.readyState?this.dataChannel.send(d):this.signalRemoteDisconnect(!1)}signalRemoteConnect(){const d=[];this.peerConnection.addEventListener("icecandidate",a=>{if(a.candidate){if(0===d.length){let b=[0,0],c;setTimeout(c=()=>{if(null!==this.peerConnection&&"disconnected"!==this.peerConnection.connectionState){const e=
|
||||
++b[1];b[0]!==d.length&&3>e?(b[0]=d.length,setTimeout(c,2E3)):(this.iceCandidateHandler(JSON.stringify(d)),d.length=0)}},2E3)}d.push({sdpMLineIndex:a.candidate.sdpMLineIndex,candidate:a.candidate.candidate})}});this.dataChannel=this.peerConnection.createDataChannel("lan");this.dataChannel.binaryType="arraybuffer";this.dataChannel.addEventListener("open",async a=>{for(;0<d.length;)await new Promise(b=>setTimeout(b,10));this.remoteDataChannelHandler(this.dataChannel)});this.dataChannel.addEventListener("message",
|
||||
a=>{this.remotePacketHandler(a.data)},!1);this.peerConnection.createOffer(a=>{this.peerConnection.setLocalDescription(a,()=>{this.descriptionHandler(JSON.stringify(a))},b=>{console.error("Failed to set local description! "+b);this.readyState=-1;this.signalRemoteDisconnect(!1)})},a=>{console.error("Failed to set create offer! "+a);this.readyState=-1;this.signalRemoteDisconnect(!1)});this.peerConnection.addEventListener("connectionstatechange",a=>{"disconnected"===this.peerConnection.connectionState?
|
||||
this.signalRemoteDisconnect(!1):"connected"===this.peerConnection.connectionState?this.readyState=2:"failed"===this.peerConnection.connectionState&&(this.readyState=-1,this.signalRemoteDisconnect(!1))})}signalRemoteDescription(d){try{this.peerConnection.setRemoteDescription(JSON.parse(d))}catch(a){console.error(a),this.readyState=-1,this.signalRemoteDisconnect(!1)}}signalRemoteICECandidate(d){try{const a=JSON.parse(d);for(let b of a)this.peerConnection.addIceCandidate(b)}catch(a){console.error(a),
|
||||
this.readyState=-1,this.signalRemoteDisconnect(!1)}}signalRemoteDisconnect(d){null!==this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null);null!==this.peerConnection&&this.peerConnection.close();d||this.remoteDisconnectHandler();this.readyState=0}}window.constructLANClient=()=>new k};window.startLANClient=()=>{"function"!==typeof window.constructLANClient&&window.initializeLANClient();return window.constructLANClient()};
|
||||
window.initializeLANServer=()=>{class k{constructor(a,b,c){this.client=a;this.peerId=b;this.peerConnection=c;this.dataChannel=null;const e=[];let f=!1;this.peerConnection.addEventListener("icecandidate",g=>{if(g.candidate){if(0===e.length){let h=[0,0],l;setTimeout(l=()=>{if(null!==this.peerConnection&&"disconnected"!==this.peerConnection.connectionState){const m=++h[1];h[0]!==e.length&&3>m?(h[0]=e.length,setTimeout(l,2E3)):(this.client.iceCandidateHandler(this.peerId,JSON.stringify(e)),e.length=0,
|
||||
f=!0)}},2E3)}e.push({sdpMLineIndex:g.candidate.sdpMLineIndex,candidate:g.candidate.candidate})}});this.peerConnection.addEventListener("datachannel",async g=>{for(;!f;)await new Promise(h=>setTimeout(h,10));this.dataChannel=g.channel;this.client.remoteClientDataChannelHandler(this.peerId,this.dataChannel);this.dataChannel.addEventListener("message",h=>{this.client.remoteClientPacketHandler(this.peerId,h.data)},!1)},!1);this.peerConnection.addEventListener("connectionstatechange",g=>{"disconnected"!==
|
||||
this.peerConnection.connectionState&&"failed"!==this.peerConnection.connectionState||this.client.signalRemoteDisconnect(this.peerId)})}disconnect(){null!==this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null);this.peerConnection.close()}setRemoteDescription(a){try{const b=JSON.parse(a);this.peerConnection.setRemoteDescription(b,()=>{"offer"===b.type&&this.peerConnection.createAnswer(c=>{this.peerConnection.setLocalDescription(c,()=>{this.client.descriptionHandler(this.peerId,JSON.stringify(c))},
|
||||
e=>{console.error('Failed to set local description for "'+this.peerId+'"! '+e);this.client.signalRemoteDisconnect(this.peerId)})},c=>{console.error('Failed to create answer for "'+this.peerId+'"! '+c);this.client.signalRemoteDisconnect(this.peerId)})},c=>{console.error('Failed to set remote description for "'+this.peerId+'"! '+c);this.client.signalRemoteDisconnect(this.peerId)})}catch(b){console.error('Failed to parse remote description for "'+this.peerId+'"! '+b),this.client.signalRemoteDisconnect(this.peerId)}}addICECandidate(a){try{const b=
|
||||
JSON.parse(a);for(let c of b)this.peerConnection.addIceCandidate(new RTCIceCandidate(c))}catch(b){console.error('Failed to parse ice candidate for "'+this.peerId+'"! '+b),this.client.signalRemoteDisconnect(this.peerId)}}}class d{constructor(){this.ICEServers=[];this.hasInit=!1;this.peerList=new Map;this.remoteClientPacketHandler=this.remoteClientDisconnectHandler=this.remoteClientDataChannelHandler=this.descriptionHandler=this.iceCandidateHandler=null}LANServerSupported(){return"undefined"!==typeof window.RTCPeerConnection}initializeServer(){}setICEServers(a){for(var b=
|
||||
this.ICEServers.length=0;b<a.length;++b){var c=a[b].split(";");1===c.length?this.ICEServers.push({urls:c[0]}):3===c.length&&this.ICEServers.push({urls:c[0],username:c[1],credential:c[2]})}}setICECandidateHandler(a){this.iceCandidateHandler=a}setDescriptionHandler(a){this.descriptionHandler=a}setRemoteClientDataChannelHandler(a){this.remoteClientDataChannelHandler=a}setRemoteClientDisconnectHandler(a){this.remoteClientDisconnectHandler=a}setRemoteClientPacketHandler(a){this.remoteClientPacketHandler=
|
||||
a}sendPacketToRemoteClient(a,b){var c=this.peerList.get(a);"undefined"!==typeof c&&null!==c&&(null!=c.dataChannel&&"open"===c.dataChannel.readyState?c.dataChannel.send(b):this.signalRemoteDisconnect(a))}signalRemoteConnect(a){try{const b=new RTCPeerConnection({iceServers:this.ICEServers,optional:[{DtlsSrtpKeyAgreement:!0}]}),c=new k(this,a,b);this.peerList.set(a,c)}catch(b){}}signalRemoteDescription(a,b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.setRemoteDescription(b)}signalRemoteICECandidate(a,
|
||||
b){a=this.peerList.get(a);"undefined"!==typeof a&&null!==a&&a.addICECandidate(b)}signalRemoteDisconnect(a){if(0===a.length){for(var b of this.peerList.values())if("undefined"!==typeof b&&null!==b){this.peerList.delete(a);try{b.disconnect()}catch(c){}this.remoteClientDisconnectHandler(a)}this.peerList.clear()}else if(b=this.peerList.get(a),"undefined"!==typeof b&&null!==b){this.peerList.delete(a);try{b.disconnect()}catch(c){}this.remoteClientDisconnectHandler(a)}}countPeers(){return this.peerList.size}}
|
||||
window.constructLANServer=()=>new d};window.startLANServer=()=>{"function"!==typeof window.constructLANServer&&window.initializeLANServer();return window.constructLANServer()};
|
||||
|
|
Loading…
Reference in New Issue
Block a user