Improved WebRTC support

This commit is contained in:
Ylian Saint-Hilaire 2018-01-18 15:43:43 -08:00
parent 92aaf754fb
commit 4106b322d6
16 changed files with 2854 additions and 128 deletions

View File

@ -44,7 +44,6 @@
<Compile Include="swarmserver.js" />
<Compile Include="multiserver.js" />
<Compile Include="pass.js" />
<Compile Include="public\relay.js" />
<Compile Include="public\scripts\amt-0.2.0.js" />
<Compile Include="public\scripts\agent-desktop-0.0.2.js" />
<Compile Include="public\scripts\amt-desktop-0.0.2.js" />
@ -58,7 +57,6 @@
<Compile Include="public\scripts\amt-wsman-ws-0.2.0.js" />
<Compile Include="public\scripts\common-0.0.1.js" />
<Compile Include="public\scripts\filesaver.1.1.20151003.js" />
<Compile Include="public\scripts\inflate.js" />
<Compile Include="public\scripts\meshcentral.js" />
<Compile Include="redirserver.js" />
<Compile Include="webserver.js" />
@ -119,8 +117,6 @@
<Content Include="public\images\mapmarker.png" />
<Content Include="public\images\meshicon50.png" />
<Content Include="public\images\trash.png" />
<Content Include="public\index.html" />
<Content Include="public\relay.htm" />
<Content Include="public\scriptblocks.txt" />
<Content Include="public\sounds\chimes.mp3" />
<Content Include="public\styles\font-awesome\css\font-awesome.min.css" />

Binary file not shown.

Binary file not shown.

View File

@ -36,6 +36,7 @@ function createMeshCore(agent) {
var wifiScanner = null;
var networkMonitor = null;
var amtscanner = null;
var nextTunnelIndex = 1;
/*
var AMTScanner = require("AMTScanner");
@ -337,7 +338,7 @@ function createMeshCore(agent) {
if (xurl != null) {
var woptions = http.parseUri(xurl);
woptions.rejectUnauthorized = 0;
sendConsoleText(JSON.stringify(woptions));
//sendConsoleText(JSON.stringify(woptions));
var tunnel = http.request(woptions);
tunnel.upgrade = onTunnelUpgrade;
tunnel.onerror = function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); }
@ -349,10 +350,8 @@ function createMeshCore(agent) {
tunnel.tcpaddr = data.tcpaddr;
tunnel.tcpport = data.tcpport;
tunnel.end();
sendConsoleText('tunnel.end() called');
// Put the tunnel in the tunnels list
var index = 1;
while (tunnels[index]) { index++; }
var index = nextTunnelIndex++;;
tunnel.index = index;
tunnels[index] = tunnel;
@ -443,6 +442,7 @@ function createMeshCore(agent) {
this.s = s;
s.httprequest = this;
s.end = onTunnelClosed;
s.tunnel = this;
if (this.tcpport != null) {
// This is a TCP relay connection, pause now and try to connect to the target.
@ -472,6 +472,7 @@ function createMeshCore(agent) {
}
function onTunnelClosed() {
if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls.
sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid);
delete tunnels[this.httprequest.index];
@ -487,6 +488,21 @@ function createMeshCore(agent) {
// If there is a upload or download active on this connection, close the file
if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; }
// Clean up WebRTC
if (this.webrtc != null) {
if (this.webrtc.rtcchannel) { try { this.webrtc.rtcchannel.close(); } catch (e) { } this.webrtc.rtcchannel.removeAllListeners('data'); this.webrtc.rtcchannel.removeAllListeners('end'); delete this.webrtc.rtcchannel; }
if (this.webrtc.websocket) { delete this.webrtc.websocket; }
try { this.webrtc.close(); } catch (e) { }
this.webrtc.removeAllListeners('connected');
this.webrtc.removeAllListeners('disconnected');
this.webrtc.removeAllListeners('dataChannel');
delete this.webrtc;
}
// Clean up WebSocket
this.removeAllListeners('data');
delete this;
}
function onTunnelSendOk() { sendConsoleText("Tunnel #" + this.index + " SendOK.", this.sessionid); }
function onTunnelData(data) {
@ -661,34 +677,71 @@ function createMeshCore(agent) {
}
}
// Attempt to setup and switch the tunnel over to WebRTC
// Called when receiving control data on WebRTC
function onTunnelWebRTCControlData(data) {
if (typeof data != 'string') return;
var obj;
try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC'); return; }
if (obj.type == 'close') {
sendConsoleText('Tunnel #' + this.xrtc.websocket.tunnel.index + ' WebRTC control close');
try { this.close(); } catch (e) { }
try { this.xrtc.close(); } catch (e) { }
}
}
// Called when receiving control data on websocket
function onTunnelControlData(data) {
sendConsoleText('onTunnelControlData: ' + data);
var obj = JSON.parse(data);
if (obj.type == 'offer') {
if (typeof data != 'string') return;
//sendConsoleText('onTunnelControlData: ' + data);
//console.log('onTunnelControlData: ' + data);
var obj;
try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON'); return; }
if (obj.type == 'close') {
// We received the close on the websocket
sendConsoleText('Tunnel #' + this.tunnel.index + ' WebSocket control close');
try { this.close(); } catch (e) { }
} else if (obj.type == 'webrtc1') {
this.write("{\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.
if (this.httprequest.protocol == 1) { // Terminal
// Switch the user input from websocket to webrtc at this point.
this.unpipe(this.httprequest.process.stdin);
this.rtcchannel.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
this.resume(); // Resume the websocket to keep receiving control data
} else if (this.httprequest.protocol == 2) { // Desktop
// Switch the user input from websocket to webrtc at this point.
this.unpipe(this.httprequest.desktop.kvm);
this.webrtc.rtcchannel.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
this.resume(); // Resume the websocket to keep receiving control data
}
} else if (obj.type == 'webrtc2') {
// Other side received websocket end of data marker, start sending data on WebRTC channel
if (this.httprequest.protocol == 1) { // Terminal
this.httprequest.process.stdout.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
} else if (this.httprequest.protocol == 2) { // Desktop
this.httprequest.desktop.kvm.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
}
} else if (obj.type == 'offer') {
// This is a WebRTC offer.
this.webrtc = rtc.createConnection();
this.webrtc.websocket = this;
this.webrtc.on('connected', function () { sendConsoleText('WebRTC connected'); });
this.webrtc.on('connected', function () { sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected'); });
this.webrtc.on('disconnected', function () { sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected'); });
this.webrtc.on('dataChannel', function (rtcchannel) {
sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
//sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
rtcchannel.xrtc = this;
this.rtcchannel = rtcchannel;
this.rtcchannel.on('data', onTunnelWebRTCControlData);
this.rtcchannel.on('end', function () { sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed'); });
if (this.websocket.httprequest.protocol == 1) { // Terminal
// This is a terminal data stream, re-setup the pipes
// Un-pipe
this.websocket.unpipe(this.websocket.httprequest.process.stdin);
//this.websocket.httprequest.process.stdout.unpipe(this.websocket);
// Re-pipe
rtcchannel.pipe(this.websocket.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
//this.websocket.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
// This is a terminal data stream, unpipe the terminal now and indicate to the other side that terminal data will no longer be received over WebSocket
this.websocket.httprequest.process.stdout.unpipe(this.websocket);
this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
} else if (this.websocket.httprequest.protocol == 2) { // Desktop
// This is a KVM data stream, re-setup the pipes
// Un-pipe
this.websocket.unpipe(this.websocket.httprequest.desktop.kvm);
//this.websocket.httprequest.desktop.kvm.unpipe(this.websocket);
// Re-pipe
rtcchannel.pipe(this.websocket.httprequest.desktop.kvm, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
//this.websocket.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
// This is a KVM data stream, unpipe the KVM now and indicate to the other side that KVM data will no longer be received over WebSocket
this.websocket.httprequest.desktop.kvm.unpipe(this.websocket);
this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
}
/*
else {

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.1.2-t",
"version": "0.1.2-u",
"keywords": [
"Remote Management",
"Intel AMT",

View File

@ -1133,6 +1133,7 @@ var CreateAmtRedirect = function (module) {
obj.user = null;
obj.pass = null;
obj.authuri = "/RedirectionService";
obj.tlsv1only = 0;
obj.connectstate = 0;
obj.protocol = module.protocol; // 1 = SOL, 2 = KVM, 3 = IDER
@ -1152,7 +1153,7 @@ var CreateAmtRedirect = function (module) {
obj.user = user;
obj.pass = pass;
obj.connectstate = 0;
obj.socket = new WebSocket(window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/webrelay.ashx?p=2&host=" + host + "&port=" + port + "&tls=" + tls + ((user == '*') ? "&serverauth=1" : "") + ((typeof pass === "undefined") ? ("&serverauth=1&user=" + user) : "")); // The "p=2" indicates to the relay that this is a REDIRECTION session
obj.socket = new WebSocket(window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/webrelay.ashx?p=2&host=" + host + "&port=" + port + "&tls=" + tls + ((user == '*') ? "&serverauth=1" : "") + ((typeof pass === "undefined") ? ("&serverauth=1&user=" + user) : "") + "&tls1only=" + obj.tlsv1only); // The "p=2" indicates to the relay that this is a REDIRECTION session
obj.socket.onopen = obj.xxOnSocketConnected;
obj.socket.onmessage = obj.xxOnMessage;
obj.socket.onclose = obj.xxOnSocketClosed;
@ -33060,7 +33061,7 @@ if (typeof module !== "undefined" && module.exports) {
});
}
var version = '0.5.7';
var version = '0.5.8';
var urlvars = null;
var amtstack;
var wsstack = null;

10
public/samples/relay.htm Normal file
View File

@ -0,0 +1,10 @@
<html>
<head>
<script type="text/javascript" src="relay.js"></script>
</head>
<body>
<script>
var relay = createMeshConnection('0D49FDEFFB778D40C062DD34A3E96113:1485387591408:b2970207326684b4de5375d097db23c85e64497eaa72013b56a8ecd8063fb9b3').connect();
</script>
</body>
</html>

48
public/samples/relay.js Normal file
View File

@ -0,0 +1,48 @@
/**
* @fileoverview Dynamic interface to MeshCentral2
* @author Ylian Saint-Hilaire
* @version v0.0.1
*/
var createMeshConnection = function (connectionId) {
var obj = {};
obj.connectionId = connectionId;
obj.state = 0;
obj.websocket = null;
obj.onStateChanged = null;
obj.onData = null;
obj.connect = function () {
if (obj.state == 0) {
obj.websocket = new WebSocket(window.location.protocol.replace('http', 'ws') + '//' + window.location.host + '/meshrelay.ashx?id=' + obj.connectionId);
obj.websocket.binaryType = "arraybuffer";
obj.websocket.onopen = function (e) { console.log('WebSocket Connected', e); };
obj.websocket.onmessage = function (e) {
console.log('WebSocket Message', e);
if ((obj.state = 1) && (e.data == 'c')) {
obj.state = 2;
if (obj.onStateChanged) { onStateChanged(obj, 2); }
console.log('WebSocket Peer Connection', e);
obj.send('bob');
} else {
if (obj.onData != null) { obj.onData(obj, e.data); }
}
};
obj.websocket.onclose = function (e) {
console.log('WebSocket Closed', e);
obj.state = 0;
if (obj.onStateChanged) { onStateChanged(obj, 0); }
};
obj.websocket.onerror = function (e) { console.log('WebSocket Error', e); };
obj.state = 1;
if (obj.onStateChanged) { onStateChanged(obj, 1); }
}
return obj;
};
obj.send = function (data) {
if ((obj.state == 2) && (obj.websocket != null)) { obj.websocket.send(data); }
};
return obj;
}

View File

@ -93,15 +93,18 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
obj.ProcessPictureMsg = function (str, X, Y) {
//if (obj.targetnode != null) obj.Debug("ProcessPictureMsg " + X + "," + Y + " - " + obj.targetnode.substring(0, 8));
var tile = new Image();
obj.tilesReceived++;
tile.xcount = obj.tilesReceived++;
//console.log('Tile #' + tile.xcount);
var r = obj.tilesReceived;
tile.src = "data:image/jpeg;base64," + btoa(str.substring(4, str.length));
tile.onload = function () {
//console.log('DecodeTile #' + this.xcount);
if (obj.Canvas != null && obj.KillDraw < r && obj.State != 0) {
obj.PendingOperations.push([r, 2, tile, X, Y]);
while (obj.DoPendingOperations()) { }
}
}
tile.error = function () { console.log('DecodeTileError'); }
}
obj.DoPendingOperations = function () {

View File

@ -50,17 +50,25 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
// Called to pass websocket control messages
obj.xxOnControlCommand = function (msg) {
var controlMsg = JSON.parse(msg);
if ((controlMsg.type == 'answer') && (obj.webrtc != null)) {
//console.log('gotAnswer', JSON.stringify(controlMsg));
var controlMsg;
try { controlMsg = JSON.parse(msg); } catch (e) { return; }
if (obj.webrtc != null) {
if (controlMsg.type == 'answer') {
obj.webrtc.setRemoteDescription(new RTCSessionDescription(controlMsg), function () { /*console.log('WebRTC remote ok');*/ }, obj.xxCloseWebRTC);
} else if (controlMsg.type == 'webrtc1') {
obj.socket.send("{\"type\":\"webrtc2\"}"); // Confirm we got end of data marker, indicates data will no longer be received on websocket.
} else if (controlMsg.type == 'webrtc2') {
// TODO: Resume/Start sending data over WebRTC
}
}
}
// Close the WebRTC connection, should be called if a problem occurs during WebRTC setup.
obj.xxCloseWebRTC = function () {
if (obj.webchannel != null) { obj.webchannel.close(); obj.webchannel = null; }
if (obj.webrtc != null) { obj.webrtc.close(); obj.webrtc = null; }
try { obj.webchannel.send("{\"type\":\"close\"}"); } catch (e) { }
if (obj.webchannel != null) { try { obj.webchannel.close(); } catch (e) { } obj.webchannel = null; }
if (obj.webrtc != null) { try { obj.webrtc.close(); } catch (e) { } obj.webrtc = null; }
obj.webRtcActive = false;
}
obj.xxOnMessage = function (e) {
@ -78,23 +86,22 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
if (obj.webrtc != null) {
obj.webchannel = obj.webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 }
obj.webchannel.onmessage = function (event) { console.log("DataChannel - onmessage", event.data); obj.xxOnMessage(event.data); };
obj.webchannel.onopen = function () { obj.webRtcActive = true; if (obj.onStateChanged != null) { obj.onStateChanged(obj, obj.State); } /*obj.webchannel.send("Browser WebRTC Hello!!!");*/ };
obj.webchannel.onclose = function (event) { obj.Stop(); }
obj.webchannel.onmessage = function (event) { obj.xxOnMessage({ data: event.data }); };
obj.webchannel.onopen = function () {
obj.webRtcActive = true;
obj.socket.send("{\"type\":\"webrtc1\"}"); // Indicate to the other side that data traffic will no longer be sent over websocket.
// TODO: Hold/Stop sending data over websocket
if (obj.onStateChanged != null) { obj.onStateChanged(obj, obj.State); }
};
obj.webchannel.onclose = function (event) { console.log('WebRTC close'); obj.Stop(); }
obj.webrtc.onicecandidate = function (e) {
if (e.candidate == null) {
//console.log('createOffer', JSON.stringify(obj.webrtcoffer));
obj.socket.send(JSON.stringify(obj.webrtcoffer)); // End of candidates, send the offer
} else {
obj.webrtcoffer.sdp += ("a=" + e.candidate.candidate + "\r\n"); // New candidate, add it to the SDP
}
}
obj.webrtc.oniceconnectionstatechange = function () {
if (obj.webrtc != null) {
//console.log('WebRTC ICE', obj.webrtc.iceConnectionState);
if ((obj.webrtc.iceConnectionState == 'disconnected') || (obj.webrtc.iceConnectionState == 'failed')) { obj.xxCloseWebRTC(); }
}
}
obj.webrtc.oniceconnectionstatechange = function () { if (obj.webrtc != null) { if ((obj.webrtc.iceConnectionState == 'disconnected') || (obj.webrtc.iceConnectionState == 'failed')) { obj.xxCloseWebRTC(); } } }
obj.webrtc.createOffer(function (offer) {
// Got the offer
obj.webrtcoffer = offer;
@ -189,13 +196,14 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
obj.Stop = function (x) {
if (obj.debugmode == 1) { console.log('stop', x); }
//obj.debug("Agent Redir Socket Stopped");
obj.webRtcActive = false;
obj.webrtc = null;
obj.webchannel = null;
obj.xxStateChange(0);
obj.connectstate = -1;
obj.xxCloseWebRTC();
if (obj.socket != null) { obj.socket.close(); obj.socket = null; }
if (obj.socket != null) {
try { obj.socket.send("{\"type\":\"close\"}"); } catch (e) { }
try { obj.socket.close(); } catch (e) { }
obj.socket = null;
}
obj.xxStateChange(0);
}
return obj;

View File

@ -23,6 +23,8 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.useZRLE = true;
obj.showmouse = true;
obj.buttonmask = 0;
//obj.inbytes = 0;
//obj.outbytes = 0;
obj.spare = null;
obj.sparew = 0;
obj.spareh = 0;
@ -33,6 +35,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.onScreenSizeChange = null;
obj.frameRateDelay = 0;
// ###BEGIN###{DesktopRotation}
obj.noMouseRotate = false;
obj.rotation = 0;
// ###END###{DesktopRotation}
@ -43,6 +46,9 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.oy = -1; // Old mouse y position
obj.focusmode = 0;
// ###END###{DesktopFocus}
// ###BEGIN###{Inflate}
obj.inflate = ZLIB.inflateInit(-15);
// ###END###{Inflate}
// Private method
obj.Debug = function (msg) { console.log(msg); }
@ -62,6 +68,8 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.ProcessData = function (data) {
if (!data) return;
// obj.Debug("KRecv(" + data.length + "): " + rstr2hex(data));
//obj.inbytes += data.length;
//obj.Debug("KRecv(" + obj.inbytes + ")");
obj.acc += data;
while (obj.acc.length > 0) {
//obj.Debug("KAcc(" + obj.acc.length + "): " + rstr2hex(obj.acc));
@ -90,6 +98,9 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
}
else if (obj.state == 3 && obj.acc.length >= 24) {
// Getting server init
// ###BEGIN###{DesktopRotation}
obj.rotation = 0; // We don't currently support screen init while rotated.
// ###END###{DesktopRotation}
var namelen = ReadInt(obj.acc, 20);
if (obj.acc.length < 24 + namelen) return;
cmdsize = 24 + namelen;
@ -208,7 +219,6 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
// Process the ZLib header if this is the first block
var ptr = 16, delta = 5, dx = 0;
if (obj.ZRLEfirst == 1) { obj.ZRLEfirst = 0; ptr += 2; delta = 7; dx = 2; } // Skip the ZLib header
if (datalen > 5 && obj.acc.charCodeAt(ptr) == 0 && ReadShortX(obj.acc, ptr + 1) == (datalen - delta)) {
// This is an uncompressed ZLib data block
@ -217,8 +227,8 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
// ###BEGIN###{Inflate}
else {
// This is compressed ZLib data, decompress and process it.
var arr = inflate(obj.acc.substring(ptr, ptr + datalen - dx));
if (arr.length > 0) { _decodeLRE(String.fromCharCode.apply(null, new Uint8Array(arr)), 0, x, y, width, height, s, arr.length); } else { obj.Debug("Invalid deflate data"); }
var arr = obj.inflate.inflate(obj.acc.substring(ptr, ptr + datalen - dx));
if (arr.length > 0) { _decodeLRE(arr, 0, x, y, width, height, s, arr.length); } else { obj.Debug("Invalid deflate data"); }
}
// ###END###{Inflate}
@ -447,10 +457,13 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.Send(String.fromCharCode(3, 1) + ShortToStr(Math.max(Math.min(obj.ox, obj.mx) - obj.focusmode, 0)) + ShortToStr(Math.max(Math.min(obj.oy, obj.my) - obj.focusmode, 0)) + ShortToStr(df + Math.abs(obj.ox - obj.mx)) + ShortToStr(df + Math.abs(obj.oy - obj.my))); // FramebufferUpdateRequest
obj.ox = obj.mx;
obj.oy = obj.my;
} else
// ###END###{DesktopFocus} {
} else {
// ###END###{DesktopFocus}
// Request the entire screen
obj.Send(String.fromCharCode(3, 1, 0, 0, 0, 0) + ShortToStr(obj.rwidth) + ShortToStr(obj.rheight)); // FramebufferUpdateRequest
// ###BEGIN###{DesktopFocus}
}
// ###END###{DesktopFocus}
}
obj.Start = function () {
@ -458,8 +471,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.state = 0;
obj.acc = "";
obj.ZRLEfirst = 1;
//obj.inbytes = 0;
//obj.outbytes = 0;
// ###BEGIN###{Inflate}
inflate_start();
obj.inflate.inflateReset();
// ###END###{Inflate}
for (var i in obj.sparecache) { delete obj.sparecache[i]; }
}
@ -472,6 +487,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.Send = function (x) {
//obj.Debug("KSend(" + x.length + "): " + rstr2hex(x));
//obj.outbytes += x.length;
obj.parent.Send(x);
}
@ -602,9 +618,11 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
obj.my = ((e.pageY - pos[1] + (scrolldiv ? scrolldiv.scrollTop : 0)) * (obj.canvas.canvas.width / Q(obj.canvasid).offsetWidth));
// ###BEGIN###{DesktopRotation}
if (obj.noMouseRotate != true) {
obj.mx2 = _crotX(obj.mx, obj.my);
obj.my = _crotY(obj.mx, obj.my);
obj.mx = obj.mx2;
}
// ###END###{DesktopRotation}
obj.Send(String.fromCharCode(5, obj.buttonmask) + ShortToStr(obj.mx) + ShortToStr(obj.my));
@ -630,7 +648,6 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
return obj.haltEvent(e);
}
obj.mousewheel = function (e) { }
obj.getPositionOfControl = function (Control) {
var Position = Array(2);

View File

@ -0,0 +1,279 @@
/* zlib-adler32.js -- JavaScript implementation for the zlib adler32.
Version: 0.2.0
LastModified: Apr 12 2012
Copyright (C) 2012 Masanao Izumo <iz@onicos.co.jp>
API documentation
==============================================================================
Usage: adler = ZLIB.adler32(adler, buf, offset, len);
Update a running Adler-32 checksum with the bytes buf[offset..offset+len-1] and
return the updated checksum. If buf is null, this function returns the
required initial value for the checksum.
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
much faster.
Usage example:
var adler = ZLIB.adler32(0, null, 0, 0);
while (read_buffer(buffer, length) != EOF) {
adler = ZLIB.adler32(adler, buffer, 0, length);
}
if (adler != original_adler) error();
==============================================================================
Usage: adler = ZLIB.adler32_combine(adler1, adler2, len2);
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
that the z_off_t type (like off_t) is a signed integer. If len2 is
negative, the result has no meaning or utility.
*/
if( typeof ZLIB === 'undefined' ) {
alert('ZLIB is not defined. SRC zlib.js before zlib-adler32.js')
}
(function() {
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2011 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
var BASE = 65521; /* largest prime smaller than 65536 */
var NMAX = 5552;
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
/* ========================================================================= */
function adler32_string(adler, buf, offset, len)
{
var sum2;
var n;
/* split Adler-32 into component sums */
sum2 = (adler >>> 16) & 0xffff;
adler &= 0xffff;
/* in case user likes doing a byte at a time, keep it fast */
if (len == 1) {
adler += buf.charCodeAt(offset) & 0xff;
if (adler >= BASE)
adler -= BASE;
sum2 += adler;
if (sum2 >= BASE)
sum2 -= BASE;
return adler | (sum2 << 16);
}
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf === null)
return 1;
/* in case short lengths are provided, keep it somewhat fast */
if (len < 16) {
while (len--) {
adler += buf.charCodeAt(offset++) & 0xff;
sum2 += adler;
}
if (adler >= BASE)
adler -= BASE;
sum2 %= BASE; /* only added so many BASE's */
return adler | (sum2 << 16);
}
/* do length NMAX blocks -- requires just one modulo operation */
while (len >= NMAX) {
len -= NMAX;
n = NMAX >> 4; /* NMAX is divisible by 16 */
do {
/* 16 sums unrolled */
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
} while (--n);
adler %= BASE;
sum2 %= BASE;
}
/* do remaining bytes (less than NMAX, still just one modulo) */
if (len) { /* avoid modulos if none remaining */
while (len >= 16) {
len -= 16;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
}
while (len--) {
adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
}
adler %= BASE;
sum2 %= BASE;
}
/* return recombined sums */
return adler | (sum2 << 16);
}
/* ========================================================================= */
function adler32_array(adler, buf, offset, len)
{
var sum2;
var n;
/* split Adler-32 into component sums */
sum2 = (adler >>> 16) & 0xffff;
adler &= 0xffff;
/* in case user likes doing a byte at a time, keep it fast */
if (len == 1) {
adler += buf[offset];
if (adler >= BASE)
adler -= BASE;
sum2 += adler;
if (sum2 >= BASE)
sum2 -= BASE;
return adler | (sum2 << 16);
}
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf === null)
return 1;
/* in case short lengths are provided, keep it somewhat fast */
if (len < 16) {
while (len--) {
adler += buf[offset++];
sum2 += adler;
}
if (adler >= BASE)
adler -= BASE;
sum2 %= BASE; /* only added so many BASE's */
return adler | (sum2 << 16);
}
/* do length NMAX blocks -- requires just one modulo operation */
while (len >= NMAX) {
len -= NMAX;
n = NMAX >> 4; /* NMAX is divisible by 16 */
do {
/* 16 sums unrolled */
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
} while (--n);
adler %= BASE;
sum2 %= BASE;
}
/* do remaining bytes (less than NMAX, still just one modulo) */
if (len) { /* avoid modulos if none remaining */
while (len >= 16) {
len -= 16;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
adler += buf[offset++]; sum2 += adler;
}
while (len--) {
adler += buf[offset++]; sum2 += adler;
}
adler %= BASE;
sum2 %= BASE;
}
/* return recombined sums */
return adler | (sum2 << 16);
}
/* ========================================================================= */
ZLIB.adler32 = function(adler, buf, offset, len)
{
if(typeof buf === 'string') {
return adler32_string(adler, buf, offset, len);
} else {
return adler32_array(adler, buf, offset, len);
}
};
ZLIB.adler32_combine = function(adler1, adler2, len2)
{
var sum1;
var sum2;
var rem;
/* for negative len, return invalid adler32 as a clue for debugging */
if (len2 < 0)
return 0xffffffff;
/* the derivation of this formula is left as an exercise for the reader */
len2 %= BASE; /* assumes len2 >= 0 */
rem = len2;
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
sum2 %= BASE;
sum1 += (adler2 & 0xffff) + BASE - 1;
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
if (sum1 >= BASE) sum1 -= BASE;
if (sum1 >= BASE) sum1 -= BASE;
if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
if (sum2 >= BASE) sum2 -= BASE;
return sum1 | (sum2 << 16);
}
}());

View File

@ -0,0 +1,246 @@
/* zlib-adler32.js -- JavaScript implementation for the zlib crc32.
Version: 0.2.0
LastModified: Apr 12 2012
Copyright (C) 2012 Masanao Izumo <iz@onicos.co.jp>
API documentation
==============================================================================
Usage: crc = ZLIB.crc32(crc, buf, offset, len);
Update a running CRC-32 with the bytes buf[offset..offset+len-1] and return the
updated CRC-32. If buf is null, this function returns the required
initial value for the for the crc. Pre- and post-conditioning (one's
complement) is performed within this function so it shouldn't be done by the
application.
Usage example:
var crc = ZLIB.crc32(0, null, 0, 0);
while (read_buffer(buffer, length) != EOF) {
crc = ZLIB.crc32(crc, buffer, 0, length);
}
if (crc != original_crc) error();
==============================================================================
Usage: crc = crc32_combine(crc1, crc2, len2);
Combine two CRC-32 check values into one. For two sequences of bytes,
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
len2.
*/
if( typeof ZLIB === 'undefined' ) {
alert('ZLIB is not defined. SRC zlib.js before zlib-crc32.js')
}
(function() {
/* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2006, 2010, 2011 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors
* instead of four steps with four exclusive-ors. This results in about a
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/
var crc_table = [
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
0x2d02ef8d ];
/* ========================================================================= */
function crc32_string(crc, buf, offset, len)
{
if (buf == null) return 0;
crc = crc ^ 0xffffffff;
while (len >= 8) {
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
len -= 8;
}
if (len) do {
crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
} while (--len);
return crc ^ 0xffffffff;
}
/* ========================================================================= */
function crc32_array(crc, buf, offset, len)
{
if (buf == null) return 0;
crc = crc ^ 0xffffffff;
while (len >= 8) {
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
len -= 8;
}
if (len) do {
crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
} while (--len);
return crc ^ 0xffffffff;
}
/* ========================================================================= */
ZLIB.crc32 = function(crc, buf, offset, len)
{
if(typeof buf === 'string') {
return crc32_string(crc, buf, offset, len);
} else {
return crc32_array(crc, buf, offset, len);
}
};
/* ========================================================================= */
var GF2_DIM = 32; /* dimension of GF(2) vectors (length of CRC) */
/* ========================================================================= */
function gf2_matrix_times(mat, vec)
{
var sum;
var mat_i = 0;
sum = 0;
while (vec) {
if (vec & 1)
sum ^= mat[mat_i];
vec >>= 1;
mat_i++;
}
return sum;
}
/* ========================================================================= */
function gf2_matrix_square(square, mat)
{
var n;
for (n = 0; n < GF2_DIM; n++)
square[n] = gf2_matrix_times(mat, mat[n]);
}
/* ========================================================================= */
ZLIB.crc32_combine = function(crc1, crc2, len2)
{
var n;
var row;
var even; /* even-power-of-two zeros operator */
var odd; /* odd-power-of-two zeros operator */
/* degenerate case (also disallow negative lengths) */
if (len2 <= 0)
return crc1;
even = new Array(GF2_DIM);
odd = new Array(GF2_DIM);
/* put operator for one zero bit in odd */
odd[0] = 0xedb88320; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
row <<= 1;
}
/* put operator for two zero bits in even */
gf2_matrix_square(even, odd);
/* put operator for four zero bits in odd */
gf2_matrix_square(odd, even);
/* apply len2 zeros to crc1 (first square will put the operator for one
zero byte, eight zero bits, in even) */
do {
/* apply zeros operator for this bit of len2 */
gf2_matrix_square(even, odd);
if (len2 & 1)
crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
/* if no more bits set, then done */
if (len2 == 0)
break;
/* another iteration of the loop with odd and even swapped */
gf2_matrix_square(odd, even);
if (len2 & 1)
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
/* if no more bits set, then done */
} while (len2 != 0);
/* return combined crc */
crc1 ^= crc2;
return crc1;
};
}());

File diff suppressed because one or more lines are too long

111
public/scripts/zlib.js Normal file
View File

@ -0,0 +1,111 @@
/* zlib.js -- JavaScript implementation for the zlib.
Version: 0.2.0
LastModified: Apr 12 2012
Copyright (C) 2012 Masanao Izumo <iz@onicos.co.jp>
The original copyright notice (zlib 1.2.6):
Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
var ZLIB = ( ZLIB || {} ); // ZLIB namespace initialization
// common definitions
if(typeof ZLIB.common_initialized === 'undefined') {
ZLIB.Z_NO_FLUSH = 0;
ZLIB.Z_PARTIAL_FLUSH = 1;
ZLIB.Z_SYNC_FLUSH = 2;
ZLIB.Z_FULL_FLUSH = 3;
ZLIB.Z_FINISH = 4;
ZLIB.Z_BLOCK = 5;
ZLIB.Z_TREES = 6;
/* Allowed flush values; see deflate() and inflate() below for details */
ZLIB.Z_OK = 0;
ZLIB.Z_STREAM_END = 1;
ZLIB.Z_NEED_DICT = 2;
ZLIB.Z_ERRNO = (-1);
ZLIB.Z_STREAM_ERROR = (-2);
ZLIB.Z_DATA_ERROR = (-3);
ZLIB.Z_MEM_ERROR = (-4);
ZLIB.Z_BUF_ERROR = (-5);
ZLIB.Z_VERSION_ERROR = (-6);
/* Return codes for the compression/decompression functions. Negative values
* are errors, positive values are used for special but normal events.
*/
ZLIB.Z_DEFLATED = 8; /* The deflate compression method (the only one supported in this version) */
/**
* z_stream constructor
* @constructor
*/
ZLIB.z_stream = function() {
this.next_in = 0; /* next input byte */
this.avail_in = 0; /* number of bytes available in input_data */
this.total_in = 0; /* total number of input bytes read so far */
this.next_out = 0; /* next output byte */
this.avail_out = 0; /* remaining free space at next_out */
this.total_out = 0; /* total number of bytes output so far */
this.msg = null; /* last error message, null if no error */
this.state = null; /* not visible by applications */
this.data_type = 0; /* best guess about the data type: binary or text */
this.adler = 0; /* TODO: adler32 value of the uncompressed data */
// zlib.js
this.input_data = ''; /* input data */
this.output_data = ''; /* output data */
this.error = 0; /* error code */
this.checksum_function = null; /* crc32(for gzip) or adler32(for zlib) */
};
/**
* TODO
* @constructor
*/
ZLIB.gz_header = function() {
this.text = 0; /* true if compressed data believed to be text */
this.time = 0; /* modification time */
this.xflags = 0; /* extra flags (not used when writing a gzip file) */
this.os = 0xff; /* operating system */
this.extra = null; /* extra field string or null if none */
this.extra_len = 0; /* this.extra.length (only when reading header) */
this.extra_max = 0; /* space at extra (only when reading header) */
this.name = null; /* file name string or null if none */
this.name_max = 0; /* space at name (only when reading header) */
this.comment = null; /* comment string or null if none */
this.comm_max = 0; /* space at comment (only when reading header) */
this.hcrc = 0; /* true if there was or will be a header crc */
this.done = 0; /* true when done reading gzip header (not used
when writing a gzip file) */
};
ZLIB.common_initialized = true;
} // common definitions

View File

@ -15,7 +15,10 @@
<script type="text/javascript" src="scripts/amt-wsman-0.2.0.js"></script>
<script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
<script type="text/javascript" src="scripts/amt-terminal-0.0.2.js"></script>
<script type="text/javascript" src="scripts/inflate.js"></script>
<script type="text/javascript" src="scripts/zlib.js"></script>
<script type="text/javascript" src="scripts/zlib-inflate.js"></script>
<script type="text/javascript" src="scripts/zlib-adler32.js"></script>
<script type="text/javascript" src="scripts/zlib-crc32.js"></script>
<script type="text/javascript" src="scripts/amt-redir-ws-0.1.0.js"></script>
<script type="text/javascript" src="scripts/amt-wsman-ws-0.2.0.js"></script>
<script type="text/javascript" src="scripts/agent-redir-ws-0.1.0.js"></script>
@ -660,6 +663,7 @@
// Check if we are in debug mode
args = parseUriArgs();
debugmode = (args.debug == 1);
attemptWebRTC = (args.webrtc == 1);
QV('p13AutoConnect', debugmode); // Files
QV('autoconnectbutton2', debugmode); // Terminal
QV('autoconnectbutton1', debugmode); // Desktop