forked from LeenkxTeam/LNXSDK
P2P Export - Nodes - Patch
This commit is contained in:
@ -1,79 +0,0 @@
|
||||
package leenkx.logicnode;
|
||||
import leenkx.system.Event;
|
||||
#if js
|
||||
import leenkx.network.Leenkx;
|
||||
#end
|
||||
import iron.object.Object;
|
||||
|
||||
class AddTorrentNode extends LogicNode {
|
||||
public var title: String;
|
||||
public var values: Array<Dynamic>;
|
||||
public var net_Url: String;
|
||||
public var data: Dynamic;
|
||||
public var runner: Bool = false;
|
||||
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
public function promiseResult(connection,torrentid,net_Url){
|
||||
#if js
|
||||
if (runner == false){
|
||||
values = [];
|
||||
var script = 'var torrentId = "' + torrentid + '";
|
||||
lx_' + net_Url +'.wt.add(torrentId, function (torrent) {
|
||||
leenkx.network.Leenkx.torrent.set("' + net_Url +'", torrent.files);
|
||||
torrent.on("done", function () {
|
||||
leenkx.network.Leenkx.connections.h["' + net_Url +'"].ontorrentdone();
|
||||
})
|
||||
});
|
||||
';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runner = true;
|
||||
promiseResult(connection,torrentid,net_Url);
|
||||
return;
|
||||
}else{
|
||||
try{
|
||||
values = leenkx.network.Leenkx.torrent.get(net_Url);
|
||||
if(values.length > 0){
|
||||
runOutput(0);
|
||||
runner = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch(error){
|
||||
haxe.Timer.delay(function () {
|
||||
promiseResult(connection,torrentid,net_Url);
|
||||
return;
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
|
||||
override function run(from:Int) {
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
var torrentid = inputs[2].get();
|
||||
if (torrentid == null) return;
|
||||
#if js
|
||||
net_Url = connection._url;
|
||||
promiseResult(connection,torrentid,net_Url);
|
||||
#end
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
#if js
|
||||
return switch (from) {
|
||||
case 1: Leenkx.id.get(net_Url);
|
||||
case 2: leenkx.network.Leenkx.torrent.get(net_Url);
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,131 +1,168 @@
|
||||
package leenkx.logicnode;
|
||||
import iron.object.Object;
|
||||
#if js
|
||||
import leenkx.network.Types;
|
||||
import leenkx.network.Util;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.LeenkxClient;
|
||||
import leenkx.network.torrent.TorrentClient;
|
||||
import leenkx.network.torrent.peer.RtcPeerPool;
|
||||
#end
|
||||
import leenkx.system.Event;
|
||||
|
||||
|
||||
class CreateLeenkxNode extends LogicNode {
|
||||
public var property0: String;
|
||||
public var property1: Bool;
|
||||
public var property2: String;
|
||||
public var property3: String;
|
||||
public var net_Url: String;
|
||||
public var data: Dynamic;
|
||||
public var client: Dynamic;
|
||||
public var value: String;
|
||||
public var listener: TEvent = null;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if js
|
||||
net_Url = inputs[1].get();
|
||||
if (net_Url == null) return;
|
||||
if(Leenkx.connections[net_Url] == null){
|
||||
var object = tree.object;
|
||||
value = Leenkx.onLoadEvent;
|
||||
listener = Event.add(value, onEvent, tree.object.uid);
|
||||
client = new leenkx.network.Leenkx(net_Url, object);
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
function onEvent() {
|
||||
#if js
|
||||
var lnxjs:Dynamic = js.Lib.global;
|
||||
var lnxCxNew = lnxjs.lnxNew;
|
||||
|
||||
if (lnxCxNew == null) {
|
||||
trace("ERROR: lnxNew not available");
|
||||
return;
|
||||
#if lnx_torrent
|
||||
net_Url = inputs[1].get();
|
||||
if (net_Url == null) return;
|
||||
if (Leenkx.connections[net_Url] == null) {
|
||||
value = Leenkx.onLoadEvent;
|
||||
listener = Event.add(value, onEvent, tree.object.uid);
|
||||
new leenkx.network.Leenkx(net_Url, tree.object);
|
||||
}
|
||||
|
||||
var lnxCn:Dynamic = lnxCxNew(net_Url);
|
||||
|
||||
lnxCn.on("connections", function(c) {
|
||||
leenkx.network.Leenkx.data.set(net_Url, c + 1);
|
||||
leenkx.network.Leenkx.connections[net_Url].onconnections();
|
||||
});
|
||||
lnxCn.on("message", function(address, message) {
|
||||
leenkx.network.Leenkx.data.set(net_Url, message);
|
||||
leenkx.network.Leenkx.id.set(net_Url, address);
|
||||
leenkx.network.Leenkx.connections[net_Url].onmessage();
|
||||
});
|
||||
lnxCn.on("seen", function(address) {
|
||||
leenkx.network.Leenkx.id.set(net_Url, address);
|
||||
leenkx.network.Leenkx.connections[net_Url].onseen();
|
||||
});
|
||||
lnxCn.on("left", function(address) {
|
||||
leenkx.network.Leenkx.id.set(net_Url, address);
|
||||
leenkx.network.Leenkx.connections[net_Url].onleft();
|
||||
});
|
||||
lnxCn.on("server", function(address) {
|
||||
leenkx.network.Leenkx.id.set(net_Url, address);
|
||||
leenkx.network.Leenkx.connections[net_Url].onserver();
|
||||
});
|
||||
lnxCn.on("ping", function(address) {
|
||||
leenkx.network.Leenkx.id.set(net_Url, address);
|
||||
leenkx.network.Leenkx.connections[net_Url].onping();
|
||||
});
|
||||
lnxCn.on("timeout", function(address) {
|
||||
leenkx.network.Leenkx.id.set(net_Url, address);
|
||||
leenkx.network.Leenkx.connections[net_Url].ontimeout();
|
||||
});
|
||||
lnxCn.on("rpc", function(address, call, args, nonce) {
|
||||
leenkx.network.Leenkx.data.set(net_Url, call);
|
||||
leenkx.network.Leenkx.id.set(net_Url, address);
|
||||
call(args);
|
||||
leenkx.network.Leenkx.connections[net_Url].onrpc();
|
||||
});
|
||||
lnxCn.on("rpc-response", function(address, nonce, response) {
|
||||
leenkx.network.Leenkx.id.set(net_Url, address);
|
||||
leenkx.network.Leenkx.connections[net_Url].onrpcresponse();
|
||||
});
|
||||
lnxCn.on("wireleft", function(wirecount, wire) {
|
||||
leenkx.network.Leenkx.data.set(net_Url, wirecount);
|
||||
leenkx.network.Leenkx.id.set(net_Url, wire.peerId);
|
||||
leenkx.network.Leenkx.connections[net_Url].onwireleft();
|
||||
});
|
||||
lnxCn.on("wireseen", function(wirecount, wire) {
|
||||
leenkx.network.Leenkx.data.set(net_Url, wirecount);
|
||||
leenkx.network.Leenkx.id.set(net_Url, wire.peerId);
|
||||
leenkx.network.Leenkx.connections[net_Url].onwireseen();
|
||||
});
|
||||
lnxCn.on("torrent", function(identifier, torrent) {
|
||||
leenkx.network.Leenkx.data.set(net_Url, torrent);
|
||||
leenkx.network.Leenkx.id.set(net_Url, identifier);
|
||||
leenkx.network.Leenkx.connections[net_Url].ontorrent();
|
||||
});
|
||||
lnxCn.on("tracker", function(identifier) {
|
||||
leenkx.network.Leenkx.id.set(net_Url, identifier);
|
||||
leenkx.network.Leenkx.connections[net_Url].ontracker();
|
||||
});
|
||||
lnxCn.on("announce", function(identifier) {
|
||||
leenkx.network.Leenkx.id.set(net_Url, identifier);
|
||||
leenkx.network.Leenkx.connections[net_Url].onannounce();
|
||||
});
|
||||
|
||||
Reflect.setField(lnxjs, "lnx_" + net_Url, lnxCn);
|
||||
Leenkx.connections[net_Url].client = lnxCn;
|
||||
|
||||
var script = 'globalThis.addEventListener("beforeunload", function (e) {
|
||||
leenkx.network.Leenkx.connections.h["' + net_Url + '"].client.destroy();
|
||||
delete e["returnValue"];
|
||||
});';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
|
||||
runOutput(0);
|
||||
#end
|
||||
}
|
||||
|
||||
function onEvent() {
|
||||
if (listener != null) {
|
||||
Event.removeListener(listener);
|
||||
listener = null;
|
||||
}
|
||||
#if lnx_torrent
|
||||
var sock = Leenkx.connections[net_Url];
|
||||
if (sock == null) return;
|
||||
if (sock.client != null) {
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
var opts:leenkx.network.torrent.Types.LeenkxOptions = {deferJoin: true};
|
||||
var nextInput = 2;
|
||||
if (property0 == "datachannel") {
|
||||
opts.transport = "datachannel";
|
||||
var imode = property2 != null ? property2 : "inherit";
|
||||
if (imode != "inherit") {
|
||||
if (inputs.length > nextInput) {
|
||||
var ice = TorrentClient.trackerUrls(inputs[nextInput].get());
|
||||
if (ice != null) {
|
||||
opts.iceServers = imode == "override" ? ice : RtcPeerPool.defaultIceServers.concat(ice);
|
||||
}
|
||||
}
|
||||
nextInput++;
|
||||
}
|
||||
}
|
||||
var tmode = property3 != null ? property3 : "inherit";
|
||||
var trackers:Array<String> = null;
|
||||
if (tmode != "inherit" && inputs.length > nextInput) {
|
||||
trackers = TorrentClient.trackerUrls(inputs[nextInput].get());
|
||||
}
|
||||
opts.announce = tmode == "override" && trackers != null ? trackers
|
||||
: trackers != null ? TorrentClient.defaultTrackers.concat(trackers)
|
||||
: TorrentClient.defaultTrackers;
|
||||
var lnxCn = new LeenkxClient(net_Url, opts);
|
||||
lnxCn.isRelay = property1 == true;
|
||||
|
||||
lnxCn.onOpen = function() {
|
||||
Leenkx.data.set(net_Url, lnxCn.lastPeerCount);
|
||||
Leenkx.id.set(net_Url, lnxCn.lastPeerId);
|
||||
sock.onopen();
|
||||
};
|
||||
lnxCn.onConnections = function(c) {
|
||||
Leenkx.data.set(net_Url, c + 1);
|
||||
sock.onconnections();
|
||||
};
|
||||
lnxCn.onMessage = function(address, message, nonce) {
|
||||
Leenkx.data.set(net_Url, message);
|
||||
Leenkx.id.set(net_Url, address);
|
||||
sock.onmessage();
|
||||
};
|
||||
lnxCn.onSeen = function(address) {
|
||||
Leenkx.id.set(net_Url, address);
|
||||
sock.onseen();
|
||||
};
|
||||
lnxCn.onLeft = function(address) {
|
||||
Leenkx.id.set(net_Url, address);
|
||||
sock.onleft();
|
||||
};
|
||||
lnxCn.onServer = function(address) {
|
||||
Leenkx.id.set(net_Url, address);
|
||||
sock.onserver();
|
||||
};
|
||||
lnxCn.onPing = function(address) {
|
||||
Leenkx.id.set(net_Url, address);
|
||||
sock.onping();
|
||||
};
|
||||
lnxCn.onTimeout = function(address) {
|
||||
Leenkx.id.set(net_Url, address);
|
||||
sock.ontimeout();
|
||||
};
|
||||
lnxCn.onWireLeft = function(wirecount, wire) {
|
||||
Leenkx.data.set(net_Url, wirecount);
|
||||
if (wire != null && wire.peerId != null) {
|
||||
Leenkx.id.set(net_Url, wire.peerId);
|
||||
}
|
||||
sock.onwireleft();
|
||||
};
|
||||
lnxCn.onWireSeen = function(wirecount, wire) {
|
||||
Leenkx.data.set(net_Url, wirecount);
|
||||
if (wire != null && wire.peerId != null) {
|
||||
Leenkx.id.set(net_Url, wire.peerId);
|
||||
}
|
||||
sock.onwireseen();
|
||||
};
|
||||
lnxCn.onTorrent = function(identifier, torrent) {
|
||||
Leenkx.data.set(net_Url, torrent);
|
||||
Leenkx.id.set(net_Url, identifier);
|
||||
sock.ontorrent();
|
||||
};
|
||||
lnxCn.onTracker = function(identifier, tracker) {
|
||||
Leenkx.id.set(net_Url, identifier);
|
||||
sock.ontracker();
|
||||
};
|
||||
lnxCn.onAnnounce = function(identifier) {
|
||||
Leenkx.id.set(net_Url, identifier);
|
||||
sock.onannounce();
|
||||
};
|
||||
lnxCn.onError = function(msg) {
|
||||
Leenkx.data.set(net_Url, msg);
|
||||
sock.onerror();
|
||||
};
|
||||
lnxCn.onTorrentAdded = function(t) {
|
||||
Leenkx.torrent.set(net_Url, t);
|
||||
Leenkx.file.set(net_Url, t.files);
|
||||
Leenkx.data.set(net_Url, t);
|
||||
sock.ontorrentadded();
|
||||
};
|
||||
lnxCn.onTorrentDone = function(t) {
|
||||
Leenkx.data.set(net_Url, t);
|
||||
sock.ontorrentdone();
|
||||
};
|
||||
|
||||
sock.client = lnxCn;
|
||||
|
||||
lnxCn.connect();
|
||||
#if (js && !kha_krom)
|
||||
js.Browser.window.addEventListener("beforeunload", function(e) {
|
||||
lnxCn.destroy();
|
||||
});
|
||||
#end
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
#if js
|
||||
#if lnx_torrent
|
||||
return switch (from) {
|
||||
case 1: Leenkx.connections[net_Url];
|
||||
case 2: Leenkx.id.get(net_Url);
|
||||
|
||||
@ -1,43 +1,100 @@
|
||||
package leenkx.logicnode;
|
||||
import leenkx.system.Event;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import iron.object.Object;
|
||||
import leenkx.network.torrent.Magnet;
|
||||
import leenkx.network.torrent.TorrentClient;
|
||||
#end
|
||||
|
||||
|
||||
class CreateTorrentNode extends LogicNode {
|
||||
public var torrent: Dynamic;
|
||||
public var net_Url: String;
|
||||
public var meta:Dynamic;
|
||||
public var metaBytes:Dynamic;
|
||||
public var magnetUri:Dynamic;
|
||||
public var infoHashHex:String;
|
||||
public var property0:String;
|
||||
public var property1:String;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
meta = null;
|
||||
metaBytes = null;
|
||||
magnetUri = null;
|
||||
infoHashHex = null;
|
||||
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
var data = inputs[2].get();
|
||||
if (data == null) return;
|
||||
net_Url = connection._url;
|
||||
var data = inputs[1].get();
|
||||
if (data == null) return;
|
||||
var mode = property1 != null ? property1 : "file";
|
||||
var opts:Dynamic = {};
|
||||
var mv = property0 != null ? Std.parseInt(property0) : null;
|
||||
if (mv != null) Reflect.setField(opts, "metaVersion", mv);
|
||||
field(2, opts, "name");
|
||||
field(3, opts, "comment");
|
||||
field(4, opts, "createdBy");
|
||||
field(5, opts, "source");
|
||||
field(6, opts, "announce");
|
||||
field(7, opts, "private");
|
||||
field(8, opts, "pieceLength");
|
||||
field(9, opts, "urlList");
|
||||
|
||||
var script = 'var file = ' + data + ';
|
||||
lx_' + net_Url +'.wt.add(file, function (torrent) {
|
||||
leenkx.network.Leenkx.file.set("' + net_Url +'", torrent.files);
|
||||
torrent.on("done", function () {
|
||||
leenkx.network.Leenkx.connections.h["' + net_Url +'"].ontorrentdone();
|
||||
});
|
||||
});
|
||||
';
|
||||
if (mode == "folder") {
|
||||
#if sys
|
||||
data = TorrentClient.readFolder(Std.string(data));
|
||||
var first:Dynamic = data[0];
|
||||
if (first != null && Reflect.field(opts, "name") == null) {
|
||||
var p = Std.string(first.path);
|
||||
var i = p.indexOf("/");
|
||||
Reflect.setField(opts, "name", p.substring(0, i >= 0 ? i : p.length));
|
||||
}
|
||||
#else
|
||||
trace("Folder mode requires a sys target";
|
||||
#end
|
||||
}
|
||||
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
var m;
|
||||
try {
|
||||
m = TorrentClient.buildMeta(data, opts);
|
||||
} catch(e:Dynamic) {
|
||||
trace(e);
|
||||
return;
|
||||
}
|
||||
meta = m;
|
||||
metaBytes = m.toTorrentBytes();
|
||||
infoHashHex = m.infoHashHex != null ? m.infoHashHex : m.infoHashV2Hex;
|
||||
magnetUri = Magnet.build(m.infoHash, m.name, m.announce, m.urlList, m.infoHashV2);
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
#if lnx_torrent
|
||||
function field(i:Int, opts:Dynamic, name:String):Void {
|
||||
if (i >= inputs.length) return;
|
||||
var v:Dynamic = inputs[i].get();
|
||||
if (v == null || Std.string(v) == "") {
|
||||
return;
|
||||
}
|
||||
if (name == "announce") {
|
||||
v = TorrentClient.trackerUrls(v);
|
||||
if (v == null) return;
|
||||
}
|
||||
Reflect.setField(opts, name, v);
|
||||
}
|
||||
#end
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return switch (from) {
|
||||
case 1: Leenkx.file.get(net_Url);
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
return switch (from) {
|
||||
case 1: meta;
|
||||
case 2: metaBytes;
|
||||
case 3: infoHashHex;
|
||||
case 4: magnetUri;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
88
leenkx/Sources/leenkx/logicnode/CreateTrackerNode.hx
Normal file
88
leenkx/Sources/leenkx/logicnode/CreateTrackerNode.hx
Normal file
@ -0,0 +1,88 @@
|
||||
package leenkx.logicnode;
|
||||
#if (lnx_torrent && (sys || kha_krom))
|
||||
import leenkx.network.torrent.tracker.HttpTracker.HttpTrackerServer;
|
||||
import leenkx.network.torrent.tracker.UdpTracker.UdpTrackerServer;
|
||||
import leenkx.network.torrent.transport.WsTrackerClient.WsTrackerServer;
|
||||
#end
|
||||
#if (lnx_torrent && sys)
|
||||
import leenkx.network.torrent.transport.WsTrackerClient.WssTrackerServer;
|
||||
#end
|
||||
|
||||
class CreateTrackerNode extends LogicNode {
|
||||
public var property0:String;
|
||||
public var tracker:Dynamic;
|
||||
public var url:String;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
tracker = null;
|
||||
url = null;
|
||||
startServer();
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
function startServer():Void {
|
||||
#if (lnx_torrent && (sys || kha_krom))
|
||||
var hv = inputs[1].get();
|
||||
var host = hv != null ? Std.string(hv) : "127.0.0.1";
|
||||
if (host == "") host = "127.0.0.1";
|
||||
var pv = inputs[2].get();
|
||||
var port = pv != null ? Std.int(Std.parseFloat(Std.string(pv))) : 0;
|
||||
if (port <= 0) port = 6969;
|
||||
var scheme = property0 != null ? property0 : "udp";
|
||||
switch (scheme) {
|
||||
case "http":
|
||||
var s = new HttpTrackerServer();
|
||||
s.onError = function(e) trace(e);
|
||||
s.start(port);
|
||||
tracker = s;
|
||||
url = "http://" + host + ":" + port + "/announce";
|
||||
case "ws":
|
||||
var s = new WsTrackerServer(host, port);
|
||||
s.onError = function(e) trace(e);
|
||||
s.start();
|
||||
tracker = s;
|
||||
url = "ws://" + host + ":" + port;
|
||||
case "wss":
|
||||
#if sys
|
||||
var cert = inputs.length > 3 ? Std.string(inputs[3].get()) : null;
|
||||
var key = inputs.length > 4 ? Std.string(inputs[4].get()) : null;
|
||||
if (cert == null || cert == "" || key == null || key == "") {
|
||||
trace("wss server needs Cert File and Key File");
|
||||
return;
|
||||
}
|
||||
var s = new WssTrackerServer(host, port, cert, key);
|
||||
s.onError = function(e) trace(e);
|
||||
s.start();
|
||||
tracker = s;
|
||||
url = "wss://" + host + ":" + port;
|
||||
#else
|
||||
trace("wss server requires a sys target");
|
||||
#end
|
||||
default:
|
||||
var s = new UdpTrackerServer();
|
||||
s.onError = function(e) trace(e);
|
||||
s.start(port);
|
||||
tracker = s;
|
||||
url = "udp://" + host + ":" + port;
|
||||
}
|
||||
#else
|
||||
trace("server mode needs a sys or krom target");
|
||||
#end
|
||||
}
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
return switch (from) {
|
||||
case 1: tracker;
|
||||
case 2: url;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
101
leenkx/Sources/leenkx/logicnode/DownloadTorrentNode.hx
Normal file
101
leenkx/Sources/leenkx/logicnode/DownloadTorrentNode.hx
Normal file
@ -0,0 +1,101 @@
|
||||
package leenkx.logicnode;
|
||||
import leenkx.system.Event;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.TorrentClient;
|
||||
#end
|
||||
|
||||
class DownloadTorrentNode extends LogicNode {
|
||||
public var net_Url:String;
|
||||
public var torrent:Dynamic;
|
||||
public var property0:String;
|
||||
public var property1:String;
|
||||
var listener:TEvent = null;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
public function promiseResult(connection, torrentid, net_Url, ?opts:Dynamic) {
|
||||
#if lnx_torrent
|
||||
var socket = Leenkx.connections[net_Url];
|
||||
if (socket == null) {
|
||||
if (listener == null) {
|
||||
var self = this;
|
||||
listener = Event.add(Leenkx.onLoadEvent, function() {
|
||||
if (Leenkx.connections[net_Url] == null) return;
|
||||
if (self.listener != null) {
|
||||
Event.removeListener(self.listener);
|
||||
self.listener = null;
|
||||
}
|
||||
self.promiseResult(connection, torrentid, net_Url, opts);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
var client = socket.client;
|
||||
if (client == null) return;
|
||||
var self = this;
|
||||
client.add(torrentid, opts, function(torrent) {
|
||||
self.torrent = torrent;
|
||||
var onReady = function() {
|
||||
self.runOutput(0);
|
||||
};
|
||||
var onDone = function() {
|
||||
self.runOutput(4);
|
||||
};
|
||||
if (torrent.ready) onReady();
|
||||
else torrent.on("ready", onReady);
|
||||
if (torrent.done) onDone();
|
||||
else torrent.on("done", onDone);
|
||||
});
|
||||
#end
|
||||
}
|
||||
|
||||
function onRemove() {
|
||||
if (listener != null) {
|
||||
Event.removeListener(listener);
|
||||
listener = null;
|
||||
}
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
var v = inputs[2].get();
|
||||
if (v == null) return;
|
||||
#if lnx_torrent
|
||||
net_Url = connection._url;
|
||||
var torrentId:Dynamic = switch (property0 != null ? property0 : "magnet") {
|
||||
case "file": v;
|
||||
case "id": TorrentClient.torrentIdFor(v);
|
||||
default: Std.string(v);
|
||||
};
|
||||
var opts:Dynamic = null;
|
||||
var tmode = property1 != null ? property1 : "inherit";
|
||||
if (tmode != "inherit" && inputs.length > 3) {
|
||||
var announce = TorrentClient.trackerUrls(inputs[3].get());
|
||||
opts = {};
|
||||
if (announce != null) opts.announce = announce;
|
||||
if (tmode == "override") opts.announceOverride = true;
|
||||
}
|
||||
promiseResult(connection, torrentId, net_Url, opts);
|
||||
#end
|
||||
}
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
var t:leenkx.network.torrent.Torrent = torrent;
|
||||
return switch (from) {
|
||||
case 1: torrent;
|
||||
case 2: t != null && t.meta != null ? t.meta.name : null;
|
||||
case 3: t != null ? t.files : null;
|
||||
case 5: t != null ? t.infoHashHex : null;
|
||||
case 6: t != null ? t.magnetURI : null;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
83
leenkx/Sources/leenkx/logicnode/GetTorrentFileNode.hx
Normal file
83
leenkx/Sources/leenkx/logicnode/GetTorrentFileNode.hx
Normal file
@ -0,0 +1,83 @@
|
||||
package leenkx.logicnode;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.Torrent;
|
||||
import leenkx.network.torrent.TorrentFile;
|
||||
#end
|
||||
|
||||
class GetTorrentFileNode extends LogicNode {
|
||||
public var property0:String;
|
||||
public var file:Dynamic;
|
||||
var net_Url:String;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
file = null;
|
||||
var id = inputs[2].get();
|
||||
var match = inputs[3].get();
|
||||
if (id != null && match != null) {
|
||||
var connection = inputs[1].get();
|
||||
if (connection != null) net_Url = connection._url;
|
||||
var socket = net_Url != null ? Leenkx.connections[net_Url] : null;
|
||||
var client = socket != null ? socket.client : null;
|
||||
var t = client != null ? client.get(id) : (Std.isOfType(id, Torrent) ? id : null);
|
||||
if (t != null) file = findFile(t, match);
|
||||
}
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
#if lnx_torrent
|
||||
function findFile(t:Torrent, match:Dynamic):TorrentFile {
|
||||
var files = t.files;
|
||||
switch (property0) {
|
||||
case "index":
|
||||
var i = Std.parseInt(Std.string(match));
|
||||
if (i != null && i >= 0 && i < files.length) {
|
||||
return files[i];
|
||||
}
|
||||
case "name":
|
||||
var s = Std.string(match);
|
||||
for (f in files) {
|
||||
if (f.name == s) return f;
|
||||
}
|
||||
case "path":
|
||||
var s = Std.string(match);
|
||||
for (f in files) {
|
||||
if (f.path == s) return f;
|
||||
}
|
||||
default:
|
||||
var s = Std.string(match);
|
||||
if (!StringTools.startsWith(s, ".")) s = "." + s;
|
||||
for (f in files) {
|
||||
if (StringTools.endsWith(f.name, s)) return f;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#end
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
var f:TorrentFile = file;
|
||||
return switch (from) {
|
||||
case 1: file;
|
||||
case 2: f != null ? f.name : null;
|
||||
case 3: f != null ? f.path : null;
|
||||
case 4: f != null ? f.length : 0;
|
||||
case 5: f != null ? f.type : null;
|
||||
case 6: f != null ? f.getBytes() : null;
|
||||
case 7: f != null;
|
||||
case 8: f != null ? f.downloaded : 0.0;
|
||||
case 9: f != null ? f.progress : 0.0;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
package leenkx.logicnode;
|
||||
import leenkx.system.Event;
|
||||
import leenkx.network.Connect;
|
||||
import iron.object.Object;
|
||||
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.LeenkxClient;
|
||||
#end
|
||||
|
||||
class LeenkxCloseConnectionNode extends LogicNode {
|
||||
public var property0: String;
|
||||
@ -12,41 +12,29 @@ class LeenkxCloseConnectionNode extends LogicNode {
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
if (connection == null) return;
|
||||
var socket = Leenkx.connections[connection._url];
|
||||
if (socket == null) return;
|
||||
|
||||
if(property0 == "client") {
|
||||
var script = '
|
||||
for (p in leenkx.network.Leenkx.connections.h["' + connection._url + '"].client.torrent._peers){
|
||||
try{
|
||||
leenkx.network.Leenkx.id.set("' + connection._url + '",p);
|
||||
leenkx.network.Leenkx.connections.h["' + connection._url + '"].client.torrent._peers[p].conn._pc.close();
|
||||
leenkx.network.Leenkx.connections.h["' + connection._url + '"].client.torrent._peers[p].conn.destroy();
|
||||
leenkx.network.Leenkx.connections.h["' + connection._url + '"].onclose();
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}
|
||||
';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
} else {
|
||||
var script = '
|
||||
try{
|
||||
var lnxConn = leenkx.network.Leenkx.connections.h["' + connection._url + '"];
|
||||
if (lnxConn && lnxConn.client && lnxConn.client.torrent && lnxConn.client.torrent._peers) {
|
||||
for (var p in lnxConn.client.torrent._peers) {
|
||||
lnxConn.client.torrent._peers[p].conn._pc.close();
|
||||
lnxConn.client.torrent._peers[p].conn.destroy();
|
||||
leenkx.network.Leenkx.id.set("' + connection._url + '", p);
|
||||
lnxConn.onclose();
|
||||
}
|
||||
}
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
var lnxCn:LeenkxClient = socket.client;
|
||||
if (property0 == "peer") {
|
||||
var id:String = inputs.length > 2 ? inputs[2].get() : null;
|
||||
if (id != null && lnxCn != null) {
|
||||
lnxCn.peers.remove(id);
|
||||
lnxCn.seenFired.remove(id);
|
||||
}
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
if (lnxCn != null) {
|
||||
lnxCn.destroy();
|
||||
socket.client = null;
|
||||
}
|
||||
Leenkx.connections.remove(connection._url);
|
||||
socket.onclose();
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package leenkx.logicnode;
|
||||
import leenkx.system.Event;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import iron.object.Object;
|
||||
#end
|
||||
|
||||
class LeenkxEventNode extends LogicNode {
|
||||
public var property0: String;
|
||||
public var property1: String;
|
||||
|
||||
public var value: String;
|
||||
@ -14,90 +14,63 @@ class LeenkxEventNode extends LogicNode {
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
tree.notifyOnInit(init);
|
||||
tree.notifyOnRemove(onRemove);
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (property0 == "client") {
|
||||
net_Url = inputs[0].get();
|
||||
switch (property1) {
|
||||
case "onopen": value = Leenkx.onOpenEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onmessage": value = Leenkx.onMessageEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onerror": value = Leenkx.onErrorEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onclose": value = Leenkx.onCloseEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onseen": value = Leenkx.onSeenEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onserver": value = Leenkx.onServerEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onconnections": value = Leenkx.onConnectionsEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onping": value = Leenkx.onPingEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onleft": value = Leenkx.onLeftEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "ontimeout": value = Leenkx.onTimeOutEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onrpc": value = Leenkx.onRpcEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onrpcresponse": value = Leenkx.onRpcResponseEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onwireleft": value = Leenkx.onWireLeftEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onwireseen": value = Leenkx.onWireSeenEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "ontorrent": value = Leenkx.onTorrentEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "ontracker": value = Leenkx.onTrackerEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onannounce": value = Leenkx.onAnnounceEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
default: throw "Failed to set client event type.";
|
||||
}
|
||||
} else if (property0 == "host") {
|
||||
#if (sys || kha_krom)
|
||||
var net_Domain = inputs[0].get();
|
||||
var net_Port = inputs[1].get();
|
||||
net_Url = "ws://" + net_Domain + ":" + Std.string(net_Port);
|
||||
switch (property1) {
|
||||
case "onopen": value = Leenkx.onOpenEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onmessage": value = Leenkx.onMessageEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onerror": value = Leenkx.onErrorEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onclose": value = Leenkx.onCloseEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
default: throw "Failed to set host event type.";
|
||||
}
|
||||
#end
|
||||
} else if (property0 == "securehost"){
|
||||
#if (sys || kha_krom)
|
||||
var net_Domain = inputs[0].get();
|
||||
var net_Port = inputs[1].get();
|
||||
net_Url = "wss://" + net_Domain + ":" + Std.string(net_Port);
|
||||
switch (property1) {
|
||||
case "onopen": value = Leenkx.onOpenEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onmessage": value = Leenkx.onMessageEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onerror": value = Leenkx.onErrorEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
case "onclose": value = Leenkx.onCloseEvent;listener = Event.add(value, onEvent, tree.object.uid);
|
||||
default: throw "Failed to set host event type.";
|
||||
}
|
||||
#end
|
||||
#if lnx_torrent
|
||||
var u:Dynamic = inputs[0].get();
|
||||
net_Url = Std.isOfType(u, String) ? u : (u != null ? u._url : null);
|
||||
switch (property1) {
|
||||
case "onopen": value = Leenkx.onOpenEvent;
|
||||
case "onmessage": value = Leenkx.onMessageEvent;
|
||||
case "onerror": value = Leenkx.onErrorEvent;
|
||||
case "onclose": value = Leenkx.onCloseEvent;
|
||||
case "onseen": value = Leenkx.onSeenEvent;
|
||||
case "onserver": value = Leenkx.onServerEvent;
|
||||
case "onconnections": value = Leenkx.onConnectionsEvent;
|
||||
case "onping": value = Leenkx.onPingEvent;
|
||||
case "onleft": value = Leenkx.onLeftEvent;
|
||||
case "ontimeout": value = Leenkx.onTimeOutEvent;
|
||||
case "onwireleft": value = Leenkx.onWireLeftEvent;
|
||||
case "onwireseen": value = Leenkx.onWireSeenEvent;
|
||||
case "ontorrent": value = Leenkx.onTorrentEvent;
|
||||
case "ontorrentadded": value = Leenkx.onTorrentAddedEvent;
|
||||
case "ontracker": value = Leenkx.onTrackerEvent;
|
||||
case "onannounce": value = Leenkx.onAnnounceEvent;
|
||||
case "ontorrentdone": value = Leenkx.onTorrentDoneEvent;
|
||||
case "onload": value = Leenkx.onLoadEvent;
|
||||
default:
|
||||
trace("Failed to set client event type");
|
||||
}
|
||||
|
||||
|
||||
listener = Event.add(value, onEvent, tree.object.uid);
|
||||
#end
|
||||
}
|
||||
|
||||
function onEvent() {
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
if (property0 == "host") {
|
||||
return switch (from) {
|
||||
case 1: Leenkx.id.get(net_Url);
|
||||
case 2: Leenkx.data.get(net_Url);
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
}
|
||||
else if (property0 == "securehost") {
|
||||
return switch (from) {
|
||||
case 1: Leenkx.id.get(net_Url);
|
||||
case 2: Leenkx.data.get(net_Url);
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
}
|
||||
else {
|
||||
return switch (from) {
|
||||
case 1: Leenkx.id.get(net_Url);
|
||||
case 2: Leenkx.data.get(net_Url);
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
function onRemove() {
|
||||
if (listener != null) {
|
||||
Event.removeListener(listener);
|
||||
listener = null;
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
#if lnx_torrent
|
||||
return switch (from) {
|
||||
case 1: Leenkx.id.get(net_Url);
|
||||
case 2: Leenkx.data.get(net_Url);
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package leenkx.logicnode;
|
||||
import leenkx.network.Connect;
|
||||
import leenkx.network.Buffer;
|
||||
import haxe.io.Bytes;
|
||||
import iron.object.Object;
|
||||
import iron.math.Vec4;
|
||||
import iron.math.Quat;
|
||||
import iron.math.Mat4;
|
||||
@ -22,140 +20,107 @@ class LeenkxMessageParserNode extends LogicNode {
|
||||
if (data == null) return;
|
||||
|
||||
api = inputs[1].get();
|
||||
if (api == null) api = "";
|
||||
|
||||
var buffer:Buffer;
|
||||
if (Std.isOfType(data, Buffer)) {
|
||||
buffer = cast data;
|
||||
} else {
|
||||
var rawBytes:Bytes;
|
||||
try {
|
||||
rawBytes = haxe.crypto.Base64.decode(Std.string(data));
|
||||
} catch(e) {
|
||||
trace("Base64 decode failed: " + e);
|
||||
return;
|
||||
}
|
||||
buffer = new Buffer();
|
||||
buffer.writeBytes(rawBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
var buffer = cast(data, Buffer);
|
||||
api = inputs[1].get();
|
||||
if(buffer.endsWith(api) == false){
|
||||
return;
|
||||
}
|
||||
**/
|
||||
var buffer = new Buffer();
|
||||
if(!StringTools.startsWith(data,api)){
|
||||
return;
|
||||
}
|
||||
switch (property0) {
|
||||
case "string":
|
||||
parsed = data.substr(api.length, data.length);
|
||||
runOutput(0);
|
||||
case "vector":
|
||||
var vec = data.substr(api.length, data.length);
|
||||
vec = StringTools.replace(vec, "(", "");
|
||||
vec = StringTools.replace(vec, ")", "");
|
||||
vec = StringTools.replace(vec, " ", "");
|
||||
vec = StringTools.trim(vec);
|
||||
var array = vec.split(",").map(Std.parseFloat);
|
||||
parsed = new Vec4( array[0], array[1], array[2], array[3] );
|
||||
runOutput(0);
|
||||
case "float":
|
||||
var flt:String = data.substr(api.length, data.length);
|
||||
var float = StringTools.trim(flt);
|
||||
parsed = Std.parseFloat(float);
|
||||
runOutput(0);
|
||||
case "integer":
|
||||
var int:String = data.substr(api.length, data.length);
|
||||
var integer = StringTools.trim(int);
|
||||
parsed = Std.parseInt(integer);
|
||||
runOutput(0);
|
||||
case "boolean":
|
||||
var boolean:String = data.substr(api.length, data.length);
|
||||
if(boolean == "true"){
|
||||
parsed = true;
|
||||
} else {
|
||||
parsed = false;
|
||||
}
|
||||
runOutput(0);
|
||||
case "transform":
|
||||
var tsfm = data.substr(api.length, data.length);
|
||||
tsfm = StringTools.replace(tsfm, "[", "");
|
||||
tsfm = StringTools.replace(tsfm, "]", "");
|
||||
tsfm = StringTools.replace(tsfm, " ", "");
|
||||
tsfm = StringTools.trim(tsfm);
|
||||
var array = tsfm.split(",").map(Std.parseFloat);
|
||||
parsed = new Mat4(
|
||||
array[0], array[1], array[2], array[3],
|
||||
array[4], array[5], array[6], array[7],
|
||||
array[8], array[9], array[10], array[11],
|
||||
array[12], array[13], array[14], array[15]
|
||||
);
|
||||
runOutput(0);
|
||||
case "rotation":
|
||||
var bytes = new haxe.io.BytesInput(buffer.readUntil(api));
|
||||
var rot = new Quat();
|
||||
for (f in Reflect.fields(rot)) {
|
||||
Reflect.setField(rot, f, bytes.readFloat());
|
||||
}
|
||||
parsed = rot;
|
||||
runOutput(0);
|
||||
default: throw "Failed to parse data.";
|
||||
}
|
||||
return;
|
||||
|
||||
|
||||
|
||||
switch (property0) {
|
||||
case "string":
|
||||
case "string":
|
||||
var bytes = buffer.readAllAvailableBytes();
|
||||
parsed = bytes.toString().substr(0, bytes.length - api.length);
|
||||
trace(parsed);
|
||||
runOutput(0);
|
||||
case "vector":
|
||||
var bytes = new haxe.io.BytesInput(buffer.readUntil(api));
|
||||
case "vector":
|
||||
var readBytes = buffer.readUntil(api);
|
||||
if (readBytes == null) return;
|
||||
var bytes = new haxe.io.BytesInput(readBytes);
|
||||
var vec = new Vec4();
|
||||
for (f in Reflect.fields(vec)) {
|
||||
Reflect.setField(vec, f, bytes.readFloat());
|
||||
}
|
||||
vec.x = bytes.readFloat();
|
||||
vec.y = bytes.readFloat();
|
||||
vec.z = bytes.readFloat();
|
||||
vec.w = bytes.readFloat();
|
||||
parsed = vec;
|
||||
runOutput(0);
|
||||
case "float":
|
||||
var bytes = new haxe.io.BytesInput(buffer.readUntil(api));
|
||||
case "float":
|
||||
var readBytes = buffer.readUntil(api);
|
||||
if (readBytes == null) return;
|
||||
var bytes = new haxe.io.BytesInput(readBytes);
|
||||
var float: Float = bytes.readFloat();
|
||||
parsed = float;
|
||||
runOutput(0);
|
||||
case "integer":
|
||||
var bytes = new haxe.io.BytesInput(buffer.readUntil(api));
|
||||
case "integer":
|
||||
var readBytes = buffer.readUntil(api);
|
||||
if (readBytes == null) return;
|
||||
var bytes = new haxe.io.BytesInput(readBytes);
|
||||
var integer: Int = bytes.readInt32();
|
||||
parsed = integer;
|
||||
runOutput(0);
|
||||
case "boolean":
|
||||
case "boolean":
|
||||
var bytes = buffer.readAllAvailableBytes();
|
||||
var boolean = bytes.toString().substr(0, bytes.length - api.length);
|
||||
if(boolean == "true"){
|
||||
if (boolean == "true") {
|
||||
parsed = true;
|
||||
} else {
|
||||
parsed = false;
|
||||
}
|
||||
runOutput(0);
|
||||
case "transform":
|
||||
var bytes = new haxe.io.BytesInput(buffer.readUntil(api));
|
||||
var readBytes = buffer.readUntil(api);
|
||||
if (readBytes == null) return;
|
||||
var bytes = new haxe.io.BytesInput(readBytes);
|
||||
var loc: Vec4 = new Vec4();
|
||||
var rot: Quat = new Quat();
|
||||
var scl: Vec4 = new Vec4();
|
||||
for (f in Reflect.fields(loc)) {
|
||||
Reflect.setField(loc, f, bytes.readFloat());
|
||||
try {
|
||||
loc.x = bytes.readFloat();
|
||||
loc.y = bytes.readFloat();
|
||||
loc.z = bytes.readFloat();
|
||||
loc.w = bytes.readFloat();
|
||||
rot.x = bytes.readFloat();
|
||||
rot.y = bytes.readFloat();
|
||||
rot.z = bytes.readFloat();
|
||||
rot.w = bytes.readFloat();
|
||||
scl.x = bytes.readFloat();
|
||||
scl.y = bytes.readFloat();
|
||||
scl.z = bytes.readFloat();
|
||||
scl.w = bytes.readFloat();
|
||||
} catch(e: Dynamic) {
|
||||
trace("readFloat error: " + e);
|
||||
return;
|
||||
}
|
||||
for (f in Reflect.fields(rot)) {
|
||||
Reflect.setField(rot, f, bytes.readFloat());
|
||||
}
|
||||
for (f in Reflect.fields(scl)) {
|
||||
Reflect.setField(scl, f, bytes.readFloat());
|
||||
}
|
||||
var transform = Mat4.identity();
|
||||
var transform = Mat4.identity();
|
||||
parsed = transform.compose(loc, rot, scl);
|
||||
runOutput(0);
|
||||
case "rotation":
|
||||
var bytes = new haxe.io.BytesInput(buffer.readUntil(api));
|
||||
case "rotation":
|
||||
var readBytes = buffer.readUntil(api);
|
||||
if (readBytes == null) return;
|
||||
var bytes = new haxe.io.BytesInput(readBytes);
|
||||
var rot = new Quat();
|
||||
for (f in Reflect.fields(rot)) {
|
||||
Reflect.setField(rot, f, bytes.readFloat());
|
||||
}
|
||||
rot.x = bytes.readFloat();
|
||||
rot.y = bytes.readFloat();
|
||||
rot.z = bytes.readFloat();
|
||||
rot.w = bytes.readFloat();
|
||||
parsed = rot;
|
||||
runOutput(0);
|
||||
default: throw "Failed to parse data.";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return switch (from) {
|
||||
|
||||
@ -1,401 +1,124 @@
|
||||
package leenkx.logicnode;
|
||||
import leenkx.network.Connect;
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.Buffer;
|
||||
import haxe.io.Bytes;
|
||||
import iron.object.Object;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.LeenkxClient;
|
||||
#end
|
||||
import iron.math.Vec4;
|
||||
import iron.math.Quat;
|
||||
import iron.math.Mat4;
|
||||
|
||||
|
||||
class LeenkxSendMessageNode extends LogicNode {
|
||||
public var property0: String;
|
||||
public var property1: String;
|
||||
public var id: String;
|
||||
public var all: Bool;
|
||||
public var property2: Bool;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if js
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
var api: String = inputs[2].get();
|
||||
if (connection == null) return;
|
||||
var api: String = inputs[2].get();
|
||||
var message: Dynamic = inputs[3].get();
|
||||
if (message == null) return;
|
||||
var broadcast: Bool = inputs.length > 4 && inputs[4].get() == true;
|
||||
var targetAddress: String = inputs.length > 5 ? inputs[5].get() : null;
|
||||
if (!broadcast && (targetAddress == null || targetAddress == "")) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if lnx_torrent
|
||||
var socket = Leenkx.connections[connection._url];
|
||||
if (socket == null) return;
|
||||
var lnxCn:LeenkxClient = socket.client;
|
||||
if (lnxCn == null) return;
|
||||
|
||||
var buffer = new Buffer();
|
||||
|
||||
switch (property1) {
|
||||
case "string":
|
||||
buffer.writeBytes(Bytes.ofString(message));
|
||||
case "vector":
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
var f:Null<Float>;
|
||||
if ((f = message.x) != null) bytesOut.writeFloat(f);
|
||||
if ((f = message.y) != null) bytesOut.writeFloat(f);
|
||||
if ((f = message.z) != null) bytesOut.writeFloat(f);
|
||||
if ((f = message.w) != null) bytesOut.writeFloat(f);
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
case "float":
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
bytesOut.writeFloat(message);
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
case "integer":
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
bytesOut.writeInt32(message);
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
case "boolean":
|
||||
if (message == true) {
|
||||
buffer.writeBytes(Bytes.ofString("true"));
|
||||
} else {
|
||||
buffer.writeBytes(Bytes.ofString("false"));
|
||||
}
|
||||
case "transform":
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
var transform:Mat4 = message;
|
||||
var loc = new Vec4();
|
||||
var rot = new Quat();
|
||||
var scale = new Vec4();
|
||||
transform.decompose(loc, rot, scale);
|
||||
bytesOut.writeFloat(loc.x);
|
||||
bytesOut.writeFloat(loc.y);
|
||||
bytesOut.writeFloat(loc.z);
|
||||
bytesOut.writeFloat(loc.w);
|
||||
bytesOut.writeFloat(rot.x);
|
||||
bytesOut.writeFloat(rot.y);
|
||||
bytesOut.writeFloat(rot.z);
|
||||
bytesOut.writeFloat(rot.w);
|
||||
bytesOut.writeFloat(scale.x);
|
||||
bytesOut.writeFloat(scale.y);
|
||||
bytesOut.writeFloat(scale.z);
|
||||
bytesOut.writeFloat(scale.w);
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
case "rotation":
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
var f:Null<Float>;
|
||||
if ((f = message.x) != null) bytesOut.writeFloat(f);
|
||||
if ((f = message.y) != null) bytesOut.writeFloat(f);
|
||||
if ((f = message.z) != null) bytesOut.writeFloat(f);
|
||||
if ((f = message.w) != null) bytesOut.writeFloat(f);
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
default: trace("Failed to send data.");
|
||||
}
|
||||
|
||||
if (api != null && api != "") {
|
||||
buffer.writeBytes(Bytes.ofString(api));
|
||||
}
|
||||
|
||||
var rawBytes = buffer.readAllAvailableBytes();
|
||||
|
||||
try {
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send(`'+ api + message + '`);
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
if (property2) {
|
||||
var payload = haxe.crypto.Base64.encode(rawBytes);
|
||||
if (broadcast) {
|
||||
lnxCn.send(null, payload);
|
||||
} else {
|
||||
lnxCn.send(targetAddress, payload);
|
||||
}
|
||||
} else {
|
||||
var script = 'lnx_' + connection._url +'.send(`' + inputs[4].get() + '`, `'+ api + message + '` );';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
lnxCn.sendRawMessage(rawBytes, broadcast ? null : targetAddress);
|
||||
}
|
||||
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
return;
|
||||
runOutput(0);
|
||||
|
||||
switch (property1) {
|
||||
case "string":
|
||||
if(property0 == "client"){
|
||||
var buffer = new Buffer();
|
||||
buffer.writeBytes(Bytes.ofString(message));
|
||||
if(api != "" || api != null){
|
||||
buffer.writeBytes(Bytes.ofString(api));
|
||||
|
||||
try {
|
||||
connection.buffer = buffer;
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send(leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
} else {
|
||||
var script = 'lnx_' + connection._url +'.send("' + inputs[4].get() + '",leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
}
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'lnx_' + connection._url + '.send(`' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}else{
|
||||
var script = 'lnx_' + connection._url + '.send(`' + inputs[4].get() + '`, `' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
case "vector":
|
||||
if(property0 == "client"){
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
var i = Reflect.fields(message);
|
||||
for (b in i) {
|
||||
bytesOut.writeFloat(Reflect.field(message, b));
|
||||
}
|
||||
var buffer = new Buffer();
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
if(api != "" || api != null){
|
||||
buffer.writeBytes(Bytes.ofString(api));
|
||||
}
|
||||
#else
|
||||
runOutput(0);
|
||||
|
||||
try {
|
||||
connection.buffer = buffer;
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send("' + api + message + '");
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
} else {
|
||||
var script = 'lnx_' + connection._url +'.send("' + inputs[4].get() + '",leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
}
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
} else {
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'lnx_' + connection._url + '.send(`' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}else{
|
||||
var script = 'lnx_' + connection._url + '.send(`' + inputs[4].get() + '`, `' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
case "float":
|
||||
if(property0 == "client"){
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
bytesOut.writeFloat(message);
|
||||
var buffer = new Buffer();
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
if(api != "" || api != null){
|
||||
buffer.writeBytes(Bytes.ofString(api));
|
||||
}
|
||||
try {
|
||||
connection.buffer = buffer;
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send(leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
} else {
|
||||
var script = 'lnx_' + connection._url +'.send("' + inputs[4].get() + '",leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
}
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
} else {
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'lnx_' + connection._url + '.send(`' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}else{
|
||||
var script = 'lnx_' + connection._url + '.send(`' + inputs[4].get() + '`, `' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
case "integer":
|
||||
if(property0 == "client"){
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
bytesOut.writeInt32(message);
|
||||
var buffer = new Buffer();
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
if(api != "" || api != null){
|
||||
buffer.writeBytes(Bytes.ofString(api));
|
||||
}
|
||||
try {
|
||||
connection.buffer = buffer;
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send(leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
} else {
|
||||
var script = 'lnx_' + connection._url +'.send("' + inputs[4].get() + '",leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
}
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
} else {
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'lnx_' + connection._url + '.send(`' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}else{
|
||||
var script = 'lnx_' + connection._url + '.send(`' + inputs[4].get() + '`, `' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
case "boolean":
|
||||
if(property0 == "client"){
|
||||
var buffer = new Buffer();
|
||||
if(message == true){
|
||||
buffer.writeBytes(Bytes.ofString("true"));
|
||||
} else {
|
||||
buffer.writeBytes(Bytes.ofString("false"));
|
||||
}
|
||||
if(api != "" || api != null){
|
||||
buffer.writeBytes(Bytes.ofString(api));
|
||||
}
|
||||
try {
|
||||
connection.buffer = buffer;
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send(leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
} else {
|
||||
var script = 'lnx_' + connection._url +'.send("' + inputs[4].get() + '",leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
}
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
} else {
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'lnx_' + connection._url + '.send(`' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}else{
|
||||
var script = 'lnx_' + connection._url + '.send(`' + inputs[4].get() + '`, `' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
case "transform":
|
||||
if(property0 == "client"){
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
var transform:Mat4 = message;
|
||||
var loc = new Vec4();
|
||||
var rot = new Quat();
|
||||
var scale = new Vec4();
|
||||
transform.decompose(loc, rot, scale);
|
||||
var l = Reflect.fields(loc);
|
||||
for (b in l) {
|
||||
bytesOut.writeFloat(Reflect.field(loc, b));
|
||||
}
|
||||
var r = Reflect.fields(rot);
|
||||
for (b in r) {
|
||||
bytesOut.writeFloat(Reflect.field(rot, b));
|
||||
}
|
||||
var s = Reflect.fields(scale);
|
||||
for (b in s) {
|
||||
bytesOut.writeFloat(Reflect.field(scale, b));
|
||||
}
|
||||
var buffer = new Buffer();
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
if(api != "" || api != null){
|
||||
buffer.writeBytes(Bytes.ofString(api));
|
||||
}
|
||||
try {
|
||||
|
||||
connection.buffer = buffer;
|
||||
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
//console.log("Mine: " + lx_8001.torrent.discovery.peerId + " || Incomming: " + p);
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send(leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
} else {
|
||||
//var script = 'lnx_' + connection._url +'.send("' + inputs[4].get() + '",leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );';
|
||||
var script = 'lnx_' + connection._url +'.send(leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
}
|
||||
case "rotation":
|
||||
if(property0 == "client"){
|
||||
var bytesOut = new haxe.io.BytesOutput();
|
||||
var i = Reflect.fields(message);
|
||||
for (b in i) {
|
||||
bytesOut.writeFloat(Reflect.field(message, b));
|
||||
}
|
||||
var buffer = new Buffer();
|
||||
buffer.writeBytes(bytesOut.getBytes());
|
||||
if(api != "" || api != null){
|
||||
buffer.writeBytes(Bytes.ofString(api));
|
||||
}
|
||||
try {
|
||||
connection.buffer = buffer;
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send(leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
} else {
|
||||
var script = 'lnx_' + connection._url +'.send("' + inputs[4].get() + '",leenkx.network.Leenkx.connections.h["'+ connection._url +'"].buffer );';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
}
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
} else {
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'lnx_' + connection._url + '.send(`' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}else{
|
||||
var script = 'lnx_' + connection._url + '.send(`' + inputs[4].get() + '`, `' + api + message + '`);';
|
||||
js.Syntax.code('(1, eval)({0})', script);
|
||||
}
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*******_________________________________________
|
||||
|
||||
try {
|
||||
|
||||
if(inputs[5].get() == true){
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
lnx_' + connection._url +'.torrent._peers[p].conn.send("' + api + message + '");
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
} else {
|
||||
var script = 'for (p in lnx_' + connection._url +'.torrent._peers){
|
||||
try{
|
||||
|
||||
lx_' + connection._url +'.torrent._peers[' + inputs[4].get() + '].conn.send("' + api + message + '");
|
||||
}catch(error){
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}';
|
||||
js.Syntax.code('(1, eval)({0})', script.toString());
|
||||
runOutput(0);
|
||||
}
|
||||
} catch(error) {
|
||||
trace("Error: " + error);
|
||||
}
|
||||
return;
|
||||
|
||||
_________________________________________*****/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ class NetworkMessageParserNode extends LogicNode {
|
||||
|
||||
var buffer = cast(data, Buffer);
|
||||
api = inputs[1].get();
|
||||
if (api == null) api = "";
|
||||
if(buffer.endsWith(api) == false){
|
||||
return;
|
||||
}
|
||||
|
||||
65
leenkx/Sources/leenkx/logicnode/OnTorrentEventNode.hx
Normal file
65
leenkx/Sources/leenkx/logicnode/OnTorrentEventNode.hx
Normal file
@ -0,0 +1,65 @@
|
||||
package leenkx.logicnode;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.Torrent;
|
||||
#end
|
||||
|
||||
class OnTorrentEventNode extends LogicNode {
|
||||
public var property0:String;
|
||||
public var eventValue:Dynamic;
|
||||
var net_Url:String;
|
||||
var torrent:Dynamic;
|
||||
var registeredTorrents:Map<String, Bool> = new Map();
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
var id = inputs[2].get();
|
||||
if (id == null) return;
|
||||
net_Url = connection._url;
|
||||
|
||||
var socket = Leenkx.connections[connection._url];
|
||||
var client = socket != null ? socket.client : null;
|
||||
var t = client != null ? client.get(id) : (Std.isOfType(id, Torrent) ? id : null);
|
||||
if (t == null) return;
|
||||
|
||||
var event = property0 != null ? property0 : "done";
|
||||
var self = this;
|
||||
var fire = function(v:Dynamic) {
|
||||
self.eventValue = v;
|
||||
self.runOutput(0);
|
||||
};
|
||||
var key = t.infoHashHex != null ? t.infoHashHex : "v2:" + t.infoHashV2Hex;
|
||||
var alreadyRegistered = registeredTorrents.exists(key);
|
||||
if (!alreadyRegistered) registeredTorrents.set(key, true);
|
||||
switch (event) {
|
||||
case "ready":
|
||||
if (t.ready) fire(null);
|
||||
else if (!alreadyRegistered) t.on("ready", function() fire(null));
|
||||
case "piece" | "wire" | "metadata" | "error":
|
||||
if (!alreadyRegistered) t.on(event, function(v) fire(v));
|
||||
default:
|
||||
if (t.done) fire(null);
|
||||
else if (!alreadyRegistered) t.on("done", function() fire(null));
|
||||
}
|
||||
torrent = t;
|
||||
#end
|
||||
}
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
return switch (from) {
|
||||
case 1: torrent;
|
||||
case 2: eventValue;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
73
leenkx/Sources/leenkx/logicnode/ParseTorrentNode.hx
Normal file
73
leenkx/Sources/leenkx/logicnode/ParseTorrentNode.hx
Normal file
@ -0,0 +1,73 @@
|
||||
package leenkx.logicnode;
|
||||
#if lnx_torrent
|
||||
import haxe.io.Bytes;
|
||||
import leenkx.network.torrent.Magnet;
|
||||
import leenkx.network.torrent.MetaInfo;
|
||||
#end
|
||||
|
||||
class ParseTorrentNode extends LogicNode {
|
||||
var meta:Dynamic;
|
||||
var magnet:Dynamic;
|
||||
var idHex:String;
|
||||
public var property0:String;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
meta = null;
|
||||
magnet = null;
|
||||
idHex = null;
|
||||
var src = inputs[1].get();
|
||||
if (src == null) return;
|
||||
|
||||
switch (property0 != null ? property0 : "magnet") {
|
||||
case "file":
|
||||
if (Std.isOfType(src, MetaInfo)) {
|
||||
meta = src;
|
||||
} else {
|
||||
var b = Std.isOfType(src, Bytes) ? src : Bytes.ofString(Std.string(src));
|
||||
try {
|
||||
meta = MetaInfo.fromTorrentBytes(b);
|
||||
} catch(e:Dynamic) {
|
||||
trace(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
case "id":
|
||||
var s = Std.string(src);
|
||||
idHex = s.length == 64 ? "v2:" + s : s;
|
||||
default:
|
||||
var m = Magnet.parse(Std.string(src));
|
||||
if (m == null) {
|
||||
return;
|
||||
}
|
||||
magnet = m;
|
||||
idHex = m.infoHashHex != null ? m.infoHashHex : m.infoHashV2Hex;
|
||||
}
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
var m:MetaInfo = meta;
|
||||
var mg:Magnet = magnet;
|
||||
return switch (from) {
|
||||
case 1: m;
|
||||
case 2: m != null ? (m.infoHashHex != null ? m.infoHashHex : m.infoHashV2Hex) : idHex;
|
||||
case 3: m != null ? m.name : (mg != null ? mg.name : null);
|
||||
case 4: m != null ? m.announce : (mg != null ? mg.trackers : null);
|
||||
case 5: m != null ? m.urlList : (mg != null ? mg.webSeeds : null);
|
||||
case 6: m != null ? m.files : null;
|
||||
case 7: m != null ? m.totalLength : 0;
|
||||
case 8: m != null ? m.toTorrentBytes() : null;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
@ -1,52 +1,124 @@
|
||||
package leenkx.logicnode;
|
||||
import leenkx.system.Event;
|
||||
import iron.object.Object;
|
||||
|
||||
#if lnx_torrent
|
||||
import haxe.io.Bytes;
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.MetaInfo;
|
||||
import leenkx.network.torrent.Torrent;
|
||||
#end
|
||||
|
||||
|
||||
class SeedTorrentNode extends LogicNode {
|
||||
public var torrent: Dynamic;
|
||||
public var net_Url: Dynamic;
|
||||
|
||||
public var torrent:Dynamic;
|
||||
public var net_Url:String;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if js
|
||||
#if lnx_torrent
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
trace("got connection");
|
||||
var data = inputs[3].get();
|
||||
if (data == null) return;
|
||||
trace("got data");
|
||||
var opts = inputs[2].get();
|
||||
if (connection == null) return;
|
||||
var src = inputs[2].get();
|
||||
net_Url = connection._url;
|
||||
|
||||
var cx = "lx_" + net_Url;
|
||||
var lx:Dynamic = untyped js.Browser.window[cx];
|
||||
var args = opts.toString();
|
||||
trace(args);
|
||||
var func = Reflect.field(lx.wt, "seed");
|
||||
if (func != null) {
|
||||
torrent = func(data, function (torrent) {
|
||||
trace('Client is seeding ' + torrent.magnetURI);
|
||||
});
|
||||
//trace(torrent);
|
||||
var socket = Leenkx.connections[connection._url];
|
||||
if (socket == null || socket.client == null) return;
|
||||
var client = socket.client;
|
||||
var self = this;
|
||||
|
||||
var onSeeded = function(t:Torrent) {
|
||||
if (t == null) return;
|
||||
self.torrent = t;
|
||||
var onDone = function() {
|
||||
self.runOutput(2);
|
||||
};
|
||||
if (t.done) onDone();
|
||||
else t.on("done", onDone);
|
||||
};
|
||||
|
||||
if (Std.isOfType(src, Torrent)) {
|
||||
var t:Torrent = src;
|
||||
t.start();
|
||||
torrent = t;
|
||||
runOutput(0);
|
||||
return;
|
||||
}
|
||||
|
||||
var meta:MetaInfo = null;
|
||||
if (Std.isOfType(src, MetaInfo)) {
|
||||
meta = cast src;
|
||||
} else if (Std.isOfType(src, Bytes)) {
|
||||
try {
|
||||
meta = MetaInfo.fromTorrentBytes(cast src);
|
||||
} catch(e:Dynamic) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (meta == null) {
|
||||
return;
|
||||
}
|
||||
var files = filesFor(meta, inputs.length > 3 ? inputs[3].get() : null);
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
client.seedMeta(meta, files, null, onSeeded);
|
||||
runOutput(0);
|
||||
#end
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
return switch (from) {
|
||||
case 1: torrent;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
}
|
||||
#if lnx_torrent
|
||||
function filesFor(meta:MetaInfo, data:Dynamic):Array<{path:String, data:Bytes}> {
|
||||
if (data == null) return null;
|
||||
var entries = meta.files;
|
||||
if (Std.isOfType(data, Bytes)) {
|
||||
var blob:Bytes = data;
|
||||
if (blob.length != meta.totalLength) return null;
|
||||
var files:Array<{path:String, data:Bytes}> = [];
|
||||
var cursor = 0;
|
||||
for (f in entries) {
|
||||
files.push({path: f.path, data: blob.sub(cursor, f.length)});
|
||||
cursor += f.length;
|
||||
}
|
||||
return files;
|
||||
}
|
||||
if (Std.isOfType(data, Array)) {
|
||||
var items:Array<Dynamic> = data;
|
||||
var files:Array<{path:String, data:Bytes}> = [];
|
||||
for (it in items) {
|
||||
var p = Reflect.field(it, "path");
|
||||
var d:Bytes = Reflect.field(it, "data");
|
||||
if (d == null) d = Reflect.field(it, "content");
|
||||
if (p == null || d == null) continue;
|
||||
var sp = Std.string(p);
|
||||
var matched = false;
|
||||
for (f in entries) {
|
||||
if (f.path == sp || StringTools.endsWith(f.path, "/" + sp)) {
|
||||
files.push({path: f.path, data: d});
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matched) files.push({path: sp, data: d});
|
||||
}
|
||||
if (files.length == entries.length) return files;
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#end
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
var t:Torrent = torrent;
|
||||
return switch (from) {
|
||||
case 1: torrent;
|
||||
case 3: t != null ? t.infoHashHex : null;
|
||||
case 4: t != null ? t.magnetURI : null;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
90
leenkx/Sources/leenkx/logicnode/SetTrackersNode.hx
Normal file
90
leenkx/Sources/leenkx/logicnode/SetTrackersNode.hx
Normal file
@ -0,0 +1,90 @@
|
||||
package leenkx.logicnode;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.Torrent;
|
||||
import leenkx.network.torrent.TorrentClient;
|
||||
#end
|
||||
|
||||
class SetTrackersNode extends LogicNode {
|
||||
public var property0:String;
|
||||
public var target:Dynamic;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
var p = property0 != null ? property0 : "add";
|
||||
switch (p) {
|
||||
case "add" | "override":
|
||||
setTorrentTrackers(p == "override");
|
||||
default:
|
||||
setTrackerProperty(p);
|
||||
}
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
#if lnx_torrent
|
||||
function setTorrentTrackers(trackerOverride:Bool):Void {
|
||||
var id = inputs[2].get();
|
||||
var urls = TorrentClient.trackerUrls(inputs[3].get());
|
||||
if (urls == null) return;
|
||||
var t:Torrent = Std.isOfType(id, Torrent) ? id : null;
|
||||
if (t == null && id != null) {
|
||||
var connection = inputs[1].get();
|
||||
var socket = connection != null ? Leenkx.connections[connection._url] : null;
|
||||
var client = socket != null ? socket.client : null;
|
||||
if (client != null) t = client.get(id);
|
||||
}
|
||||
if (t != null) {
|
||||
target = t;
|
||||
if (trackerOverride) {
|
||||
t.setTrackers(urls);
|
||||
} else {
|
||||
for (u in urls) t.addTracker(u);
|
||||
}
|
||||
} else if (id == null) {
|
||||
target = null;
|
||||
if (trackerOverride) {
|
||||
TorrentClient.defaultTrackers = urls;
|
||||
} else {
|
||||
TorrentClient.mergeTrackers(TorrentClient.defaultTrackers, urls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setTrackerProperty(prop:String):Void {
|
||||
var tracker:Dynamic = inputs[1].get();
|
||||
if (tracker == null) return;
|
||||
var v = inputs[2].get();
|
||||
if (v == null) return;
|
||||
var field = prop == "interval" ? "intervalSec" : prop;
|
||||
var val:Dynamic = field == "trackerId" ? Std.string(v)
|
||||
: Std.int(Std.parseFloat(Std.string(v)));
|
||||
var setter:Dynamic = field == "intervalSec"
|
||||
&& Reflect.field(tracker, "intervalSec") == null
|
||||
? Reflect.field(tracker, "setAnnounceInterval") : null;
|
||||
if (setter != null) {
|
||||
try {
|
||||
Reflect.callMethod(tracker, setter, [(val:Int) * 1000]);
|
||||
} catch(e:Dynamic) {}
|
||||
} else {
|
||||
Reflect.setField(tracker, field, val);
|
||||
}
|
||||
target = tracker;
|
||||
}
|
||||
#end
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
return switch (from) {
|
||||
case 1: target;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
74
leenkx/Sources/leenkx/logicnode/TorrentClientInfoNode.hx
Normal file
74
leenkx/Sources/leenkx/logicnode/TorrentClientInfoNode.hx
Normal file
@ -0,0 +1,74 @@
|
||||
package leenkx.logicnode;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.Torrent;
|
||||
#end
|
||||
|
||||
class TorrentClientInfoNode extends LogicNode {
|
||||
var stats:Dynamic;
|
||||
var list:Array<Dynamic>;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
list = [];
|
||||
stats = {downRate: 0.0, upRate: 0.0, progress: 0.0, ratio: 0.0};
|
||||
var connection = inputs[1].get();
|
||||
if (connection != null) {
|
||||
var socket = Leenkx.connections[connection._url];
|
||||
var client = socket != null ? socket.client : null;
|
||||
if (client != null) collect(client);
|
||||
}
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
#if lnx_torrent
|
||||
function collect(client:Dynamic) {
|
||||
var down = 0.0;
|
||||
var up = 0.0;
|
||||
var received = 0.0;
|
||||
var sent = 0.0;
|
||||
var total = 0.0;
|
||||
var left = 0.0;
|
||||
var torrents:Map<String, Torrent> = client.torrents;
|
||||
for (t in torrents) {
|
||||
list.push(t);
|
||||
var s = t.getStats();
|
||||
down += s.downRate;
|
||||
up += s.upRate;
|
||||
received += s.downloaded;
|
||||
sent += s.uploaded;
|
||||
if (t.meta != null) {
|
||||
total += t.meta.totalLength;
|
||||
left += s.left;
|
||||
}
|
||||
}
|
||||
stats = {
|
||||
downRate: down,
|
||||
upRate: up,
|
||||
progress: total > 0 ? 1.0 - left / total : 0.0,
|
||||
ratio: received > 0 ? sent / received : 0.0
|
||||
};
|
||||
}
|
||||
#end
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
return switch (from) {
|
||||
case 1: list;
|
||||
case 2: list.length;
|
||||
case 3: stats.downRate;
|
||||
case 4: stats.upRate;
|
||||
case 5: stats.progress;
|
||||
case 6: stats.ratio;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
}
|
||||
93
leenkx/Sources/leenkx/logicnode/TorrentControlNode.hx
Normal file
93
leenkx/Sources/leenkx/logicnode/TorrentControlNode.hx
Normal file
@ -0,0 +1,93 @@
|
||||
package leenkx.logicnode;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.Torrent;
|
||||
#end
|
||||
|
||||
class TorrentControlNode extends LogicNode {
|
||||
public var property0:String;
|
||||
var net_Url:String;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
var id = inputs[2].get();
|
||||
if (id == null) return;
|
||||
net_Url = connection._url;
|
||||
|
||||
var socket = Leenkx.connections[connection._url];
|
||||
if (socket == null) return;
|
||||
var client = socket.client;
|
||||
var t = client != null ? client.get(id) : (Std.isOfType(id, Torrent) ? id : null);
|
||||
var action = property0 != null ? property0 : "remove";
|
||||
|
||||
var file:Dynamic = inputs.length > 3 ? inputs[3].get() : null;
|
||||
var t2 = t;
|
||||
var startB = 0;
|
||||
var endB = -1;
|
||||
if (file != null) {
|
||||
startB = file.offset;
|
||||
endB = file.offset + file.length - 1;
|
||||
if (t2 == null) t2 = file.torrent;
|
||||
} else {
|
||||
var sv = inputs.length > 4 ? inputs[4].get() : null;
|
||||
var ev = inputs.length > 5 ? inputs[5].get() : null;
|
||||
if (sv != null && Std.string(sv) != "") {
|
||||
startB = Std.int(Std.parseFloat(Std.string(sv)));
|
||||
}
|
||||
if (ev != null && Std.string(ev) != "") {
|
||||
endB = Std.int(Std.parseFloat(Std.string(ev)));
|
||||
}
|
||||
}
|
||||
var pv = inputs.length > 6 ? inputs[6].get() : null;
|
||||
var priority = pv != null && Std.string(pv) != "" ? Std.int(Std.parseFloat(Std.string(pv))) : null;
|
||||
|
||||
switch (action) {
|
||||
case "start":
|
||||
if (t != null) t.start();
|
||||
case "stop":
|
||||
if (t != null) t.stop();
|
||||
case "select", "critical", "deselect":
|
||||
if (t2 != null) {
|
||||
if (endB < 0) {
|
||||
endB = t2.meta != null ? t2.meta.totalLength - 1 : 0;
|
||||
}
|
||||
if (action == "critical") {
|
||||
t2.critical(startB, endB);
|
||||
} else if (action == "select") {
|
||||
t2.select(startB, endB, priority);
|
||||
} else {
|
||||
t2.deselect(startB, endB, priority);
|
||||
}
|
||||
}
|
||||
case "add-peer":
|
||||
var peer = inputs.length > 3 ? inputs[3].get() : null;
|
||||
if (t != null && peer != null) {
|
||||
t.addPeer(Std.string(peer));
|
||||
}
|
||||
case "add-web-seed":
|
||||
var url = inputs.length > 3 ? inputs[3].get() : null;
|
||||
if (t != null && url != null) {
|
||||
t.addWebSeed(Std.string(url));
|
||||
}
|
||||
case "remove", "remove-data":
|
||||
var hex = t != null ? t.infoHashHex : Std.string(id);
|
||||
if (hex == null) hex = Std.string(id);
|
||||
if (client != null) {
|
||||
client.remove(hex, action == "remove-data");
|
||||
}
|
||||
if (t != null && Leenkx.torrent.get(net_Url) == t) {
|
||||
Leenkx.torrent.remove(net_Url);
|
||||
Leenkx.file.remove(net_Url);
|
||||
}
|
||||
default:
|
||||
}
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
}
|
||||
74
leenkx/Sources/leenkx/logicnode/TorrentInfoNode.hx
Normal file
74
leenkx/Sources/leenkx/logicnode/TorrentInfoNode.hx
Normal file
@ -0,0 +1,74 @@
|
||||
package leenkx.logicnode;
|
||||
#if lnx_torrent
|
||||
import leenkx.network.Leenkx;
|
||||
import leenkx.network.torrent.Torrent;
|
||||
import leenkx.network.torrent.TorrentClient;
|
||||
#end
|
||||
|
||||
class TorrentInfoNode extends LogicNode {
|
||||
public var torrent:Dynamic;
|
||||
public var net_Url:String;
|
||||
|
||||
public function new(tree:LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function run(from:Int) {
|
||||
#if lnx_torrent
|
||||
var id = inputs[2].get();
|
||||
if (id == null) return;
|
||||
torrent = null;
|
||||
|
||||
if (Std.isOfType(id, Torrent)) {
|
||||
torrent = id;
|
||||
} else {
|
||||
var connection = inputs[1].get();
|
||||
if (connection == null) return;
|
||||
net_Url = connection._url;
|
||||
var socket = Leenkx.connections[net_Url];
|
||||
if (socket == null || socket.client == null) return;
|
||||
torrent = socket.client.get(id);
|
||||
}
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
|
||||
override function get(from:Int):Dynamic {
|
||||
#if lnx_torrent
|
||||
var t:Torrent = torrent;
|
||||
return switch (from) {
|
||||
case 1: t != null ? t.infoHashHex : null;
|
||||
case 2: t != null && t.meta != null ? t.meta.name : null;
|
||||
case 3: t != null ? t.numPeers : 0;
|
||||
case 4: progress(t);
|
||||
case 5: t != null ? t.getStats().downloaded : 0.0;
|
||||
case 6: t != null ? t.getStats().uploaded : 0.0;
|
||||
case 7: t != null ? t.done : false;
|
||||
case 8: t != null ? t.magnetURI : null;
|
||||
case 9: t != null ? t.files : null;
|
||||
case 10: t != null && t.meta != null ? t.meta.numPieces : 0;
|
||||
case 11: t != null && t.meta != null ? t.meta.pieceLength : 0;
|
||||
case 12: t != null && t.meta != null ? t.meta.totalLength : 0;
|
||||
case 13: t != null && t.meta != null ? t.meta.comment : null;
|
||||
case 14: t != null && t.meta != null ? t.meta.createdBy : null;
|
||||
case 15: t != null && t.meta != null ? t.meta.protocolVersion : 1;
|
||||
case 16: t != null ? t.infoHashV2Hex : null;
|
||||
case 17: t != null ? t.getStats().downRate : 0.0;
|
||||
case 18: t != null ? t.getStats().upRate : 0.0;
|
||||
case 19: t != null ? t.stopped : false;
|
||||
case 20: t;
|
||||
default: throw "Unreachable";
|
||||
}
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
}
|
||||
|
||||
#if lnx_torrent
|
||||
function progress(t:Torrent):Float {
|
||||
if (t == null || t.meta == null || t.meta.totalLength == 0) return 0;
|
||||
var stats = t.getStats();
|
||||
return 1.0 - stats.left / t.meta.totalLength;
|
||||
}
|
||||
#end
|
||||
}
|
||||
@ -121,7 +121,6 @@ class Leenkx {
|
||||
class LeenkxSocket {
|
||||
public var _url:String;
|
||||
public var client:LeenkxClient;
|
||||
public var torrentClient:leenkx.network.torrent.TorrentClient;
|
||||
public var buffer:Dynamic;
|
||||
public var onopen:Void->Void;
|
||||
public var onclose:Void->Void;
|
||||
|
||||
@ -9,7 +9,8 @@ import leenkx.network.torrent.TorrentInfo;
|
||||
|
||||
class LeenkxClient {
|
||||
|
||||
static var PEERTIMEOUT:Float = 5 * 60 * 1000;
|
||||
public static var PEERTIMEOUT:Float = 5 * 60 * 1000;
|
||||
public static var defaultHeartbeat:Int = 30000;
|
||||
|
||||
public var identifier:String;
|
||||
public var seed:String;
|
||||
@ -53,6 +54,54 @@ class LeenkxClient {
|
||||
private var deferredOpts:TransportOpts = null;
|
||||
private var heartbeatInterval:Int = 30000;
|
||||
|
||||
public var torrents(get, never):Map<String, Torrent>;
|
||||
public var onTorrentAdded:Torrent -> Void;
|
||||
public var onTorrentDone:Torrent -> Void;
|
||||
var swarm:TorrentClient = null;
|
||||
|
||||
function get_torrents():Map<String, Torrent> {
|
||||
return swarm != null ? swarm.torrents : [];
|
||||
}
|
||||
|
||||
function getSwarm():TorrentClient {
|
||||
if (swarm == null) {
|
||||
swarm = new TorrentClient();
|
||||
swarm.onError = function(e) {
|
||||
if (onError != null) onError(e);
|
||||
};
|
||||
swarm.onTorrentAdded = function(t) {
|
||||
if (onTorrentAdded != null) onTorrentAdded(t);
|
||||
};
|
||||
swarm.onTorrentDone = function(t) {
|
||||
if (onTorrentDone != null) onTorrentDone(t);
|
||||
};
|
||||
}
|
||||
return swarm;
|
||||
}
|
||||
|
||||
public function add(torrentId:Dynamic, ?opts:Dynamic, ?cb:Torrent -> Void):Torrent {
|
||||
return getSwarm().add(torrentId, opts, cb);
|
||||
}
|
||||
|
||||
public function seedMeta(meta:MetaInfo,
|
||||
files:Array<{path:String, data:Bytes}>,
|
||||
?opts:Dynamic, ?cb:Torrent -> Void):Torrent {
|
||||
return getSwarm().seedMeta(meta, files, opts, cb);
|
||||
}
|
||||
|
||||
public function get(id:Dynamic):Torrent {
|
||||
if (Std.isOfType(id, Torrent)) return id;
|
||||
return swarm != null ? swarm.get(id) : null;
|
||||
}
|
||||
|
||||
public function remove(infoHashHex:String, ?deleteData:Bool):Void {
|
||||
if (swarm != null) swarm.remove(infoHashHex, deleteData);
|
||||
}
|
||||
|
||||
public function listen(port:Int):Void {
|
||||
getSwarm().listen(port);
|
||||
}
|
||||
|
||||
public function new(?identifier:String, ?opts:LeenkxOptions) {
|
||||
if (identifier != null && !Std.isOfType(identifier, String)) {
|
||||
opts = cast identifier;
|
||||
@ -60,7 +109,7 @@ class LeenkxClient {
|
||||
}
|
||||
opts = opts != null ? opts : {};
|
||||
|
||||
this.announce = opts.announce != null ? opts.announce : ["wss://ws1.leenkx.com"];
|
||||
this.announce = opts.announce != null ? opts.announce : TorrentClient.defaultTrackers;
|
||||
this.timeout = opts.timeout != null ? opts.timeout : PEERTIMEOUT;
|
||||
|
||||
if (opts.seed != null) {
|
||||
@ -90,7 +139,7 @@ class LeenkxClient {
|
||||
|
||||
createTransport(opts, opts.deferJoin == true);
|
||||
|
||||
this.heartbeatInterval = opts.heartbeat != null ? opts.heartbeat : 30000;
|
||||
this.heartbeatInterval = opts.heartbeat != null ? opts.heartbeat : defaultHeartbeat;
|
||||
}
|
||||
|
||||
function createTransport(opts:LeenkxOptions, defer:Bool):Void {
|
||||
@ -281,6 +330,10 @@ class LeenkxClient {
|
||||
}
|
||||
var packet = makePacket({y: PacketType.Leave});
|
||||
sendRaw(packet);
|
||||
if (swarm != null) {
|
||||
swarm.destroy();
|
||||
swarm = null;
|
||||
}
|
||||
if (transport != null) {
|
||||
transport.destroy(cb);
|
||||
} else if (cb != null) {
|
||||
|
||||
@ -39,12 +39,9 @@ class Torrent {
|
||||
public var announcePort:Int = 0;
|
||||
public var downloadDir:String = null;
|
||||
|
||||
public function getStats():{downloaded:Float, uploaded:Float,
|
||||
left:Float, downRate:Float, upRate:Float} {
|
||||
public function getStats():{downloaded:Float, uploaded:Float, left:Float, downRate:Float, upRate:Float} {
|
||||
var total = meta != null ? meta.totalLength : 0;
|
||||
var downloaded = pieces != null
|
||||
? Math.min(pieces.numHave * (meta.pieceLength:Float), total)
|
||||
: 0;
|
||||
var downloaded = pieces != null ? Math.min(pieces.numHave * (meta.pieceLength:Float), total) : 0;
|
||||
var now = haxe.Timer.stamp();
|
||||
var dt = now - lastStatT;
|
||||
var downRate:Float = 0;
|
||||
@ -93,8 +90,7 @@ class Torrent {
|
||||
public function new(infoHash:Bytes, peerId:Bytes, trackers:Array<String>, ?meta:MetaInfo, ?storage:IStorage, ?downloadDir:String) {
|
||||
TorrentClient.initMain();
|
||||
this.infoHash = infoHash;
|
||||
this.infoHashHex = infoHash != null
|
||||
? Crypto.toHex(infoHash) : null;
|
||||
this.infoHashHex = infoHash != null ? Crypto.toHex(infoHash) : null;
|
||||
this.peerId = peerId;
|
||||
this.trackers = trackers;
|
||||
this.storage = storage;
|
||||
@ -121,12 +117,9 @@ class Torrent {
|
||||
function setMeta(m:MetaInfo):Void {
|
||||
meta = m;
|
||||
if (storage == null) {
|
||||
var sz = m.storageLength > 0 ? m.storageLength
|
||||
: m.totalLength;
|
||||
var sz = m.storageLength > 0 ? m.storageLength : m.totalLength;
|
||||
#if (sys || kha_krom)
|
||||
storage = downloadDir != null
|
||||
? new FileTreeStorage(downloadDir, m.files)
|
||||
: new MemoryStorage(sz);
|
||||
storage = downloadDir != null ? new FileTreeStorage(downloadDir, m.files) : new MemoryStorage(sz);
|
||||
#else
|
||||
storage = new MemoryStorage(sz);
|
||||
#end
|
||||
@ -139,8 +132,7 @@ class Torrent {
|
||||
if (m.fileHashes == null && m.files != null) {
|
||||
m.fileHashes = [for (f in m.files) null];
|
||||
}
|
||||
files = [for (f in m.files)
|
||||
new TorrentFile(f, storage, this)];
|
||||
files = [for (f in m.files) new TorrentFile(f, storage, this)];
|
||||
infoHashV2 = m.infoHashV2;
|
||||
infoHashV2Hex = m.infoHashV2Hex;
|
||||
if (infoHash == null && m.infoHash != null) {
|
||||
@ -151,8 +143,7 @@ class Torrent {
|
||||
if (m.urlList == null && pendingWebSeeds != null) {
|
||||
m.urlList = pendingWebSeeds;
|
||||
}
|
||||
magnetURI = Magnet.build(m.infoHash, m.name, trackers,
|
||||
m.urlList, m.infoHashV2);
|
||||
magnetURI = Magnet.build(m.infoHash, m.name, trackers, m.urlList, m.infoHashV2);
|
||||
ready = true;
|
||||
initWebSeeds();
|
||||
emit1("metadata", m);
|
||||
@ -214,6 +205,24 @@ class Torrent {
|
||||
return startTracker(url);
|
||||
}
|
||||
|
||||
public function setTrackers(urls:Array<String>):Void {
|
||||
if (stopped) {
|
||||
trackers = urls != null ? urls.copy() : [];
|
||||
return;
|
||||
}
|
||||
if (rtcPool != null) {
|
||||
rtcPool.close();
|
||||
rtcPool = null;
|
||||
}
|
||||
for (t in httpTrackers) t.stop();
|
||||
for (t in udpTrackers) t.stop();
|
||||
httpTrackers = [];
|
||||
udpTrackers = [];
|
||||
trackerObjects = [];
|
||||
trackers = urls != null ? urls.copy() : [];
|
||||
startTrackers();
|
||||
}
|
||||
|
||||
function startTracker(url:String):Dynamic {
|
||||
var infoHashBin = TorrentInfo.toBinaryString(infoHash);
|
||||
var peerIdBin = TorrentInfo.toBinaryString(peerId);
|
||||
@ -231,9 +240,7 @@ class Torrent {
|
||||
}
|
||||
#if (sys || kha_krom)
|
||||
else if (url.indexOf("http") == 0) {
|
||||
var t = new leenkx.network.torrent.tracker.HttpTracker(
|
||||
url, infoHash, peerId,
|
||||
announcePort > 0 ? announcePort : 6881);
|
||||
var t = new leenkx.network.torrent.tracker.HttpTracker(url, infoHash, peerId, announcePort > 0 ? announcePort : 6881);
|
||||
t.statsProvider = getStats;
|
||||
t.onPeers = onClassicPeers;
|
||||
t.onError = function(e) {
|
||||
@ -246,9 +253,7 @@ class Torrent {
|
||||
#end
|
||||
#if (sys || kha_krom)
|
||||
else if (url.indexOf("udp") == 0) {
|
||||
var t = new leenkx.network.torrent.tracker.UdpTracker(
|
||||
url, infoHash, peerId,
|
||||
announcePort > 0 ? announcePort : 6881);
|
||||
var t = new leenkx.network.torrent.tracker.UdpTracker(url, infoHash, peerId, announcePort > 0 ? announcePort : 6881);
|
||||
t.statsProvider = getStats;
|
||||
t.onPeers = onClassicPeers;
|
||||
t.onError = function(e) {
|
||||
@ -272,8 +277,7 @@ class Torrent {
|
||||
for (p in list) {
|
||||
var key = "tcp:" + p.host + ":" + p.port;
|
||||
if (wires.exists(key)) continue;
|
||||
var ch = new leenkx.network.torrent.peer.TcpPeer(
|
||||
p.host, p.port);
|
||||
var ch = new leenkx.network.torrent.peer.TcpPeer(p.host, p.port);
|
||||
addWire(key, ch);
|
||||
}
|
||||
}
|
||||
@ -308,8 +312,7 @@ class Torrent {
|
||||
requestBlocks(key);
|
||||
};
|
||||
wire.onHave = function(index) {
|
||||
if (meta == null || index < 0
|
||||
|| index >= meta.numPieces) return;
|
||||
if (meta == null || index < 0 || index >= meta.numPieces) return;
|
||||
var bf = peerBitfields.get(key);
|
||||
if (bf != null && index < bf.length) bf[index] = true;
|
||||
requestBlocks(key);
|
||||
@ -317,17 +320,13 @@ class Torrent {
|
||||
wire.onPiece = function(index, begin, data) {
|
||||
var n = outstanding.get(key);
|
||||
if (n != null && n > 0) outstanding.set(key, n - 1);
|
||||
if (pieces != null && index >= 0
|
||||
&& index < meta.numPieces
|
||||
&& pieces.addBlock(index, begin, data)) {
|
||||
if (pieces != null && index >= 0 && index < meta.numPieces && pieces.addBlock(index, begin, data)) {
|
||||
broadcastHave(index);
|
||||
}
|
||||
requestBlocks(key);
|
||||
};
|
||||
wire.onRequest = function(index, begin, length) {
|
||||
if (wire.amChoking || pieces == null || index < 0
|
||||
|| index >= meta.numPieces || begin < 0 || length <= 0
|
||||
|| begin + length > meta.pieceSize(index)) return;
|
||||
if (wire.amChoking || pieces == null || index < 0 || index >= meta.numPieces || begin < 0 || length <= 0 || begin + length > meta.pieceSize(index)) return;
|
||||
if (!pieces.have[index]) return;
|
||||
var data = pieces.readBlock(index, begin, length);
|
||||
uploadedBytes += data.length;
|
||||
@ -384,8 +383,7 @@ class Torrent {
|
||||
var out:Array<Bool> = [];
|
||||
for (i in 0...n) {
|
||||
var byte = i >> 3;
|
||||
out.push(byte < bf.length
|
||||
&& (bf.get(byte) & (0x80 >> (i & 7))) != 0);
|
||||
out.push(byte < bf.length && (bf.get(byte) & (0x80 >> (i & 7))) != 0);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@ -479,8 +477,7 @@ class Torrent {
|
||||
if (host == "" || port == null) return false;
|
||||
var key = "tcp:" + host + ":" + port;
|
||||
if (wires.exists(key)) return false;
|
||||
addWire(key,
|
||||
new leenkx.network.torrent.peer.TcpPeer(host, port));
|
||||
addWire(key, new leenkx.network.torrent.peer.TcpPeer(host, port));
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
@ -509,8 +506,7 @@ class Torrent {
|
||||
var pendingLayers:Map<Int, {arr:Array<Bytes>, got:Int}> = [];
|
||||
|
||||
function pieceLayerBase():Int {
|
||||
return Std.int(Math.log(meta.pieceLength / 16384)
|
||||
/ Math.log(2));
|
||||
return Std.int(Math.log(meta.pieceLength / 16384) / Math.log(2));
|
||||
}
|
||||
|
||||
function requestPieceLayer(wire:WireProtocol, fi:Int):Void {
|
||||
@ -528,8 +524,7 @@ class Torrent {
|
||||
if (chunk > 512) chunk = 512;
|
||||
var len = 2;
|
||||
while (len < chunk) len <<= 1;
|
||||
wire.sendHashRequest(root, pieceLayerBase(), sent,
|
||||
len, 0);
|
||||
wire.sendHashRequest(root, pieceLayerBase(), sent, len, 0);
|
||||
hashReqNext.set(fi, sent + len);
|
||||
hashReqTime.set(fi, haxe.Timer.stamp());
|
||||
}
|
||||
@ -547,11 +542,9 @@ class Torrent {
|
||||
if (count <= 0) return;
|
||||
for (fi in 0...meta.files.length) {
|
||||
var f = meta.files[fi];
|
||||
if (f.piecesRoot == null
|
||||
|| !bytesEq(root, f.piecesRoot)) continue;
|
||||
if (f.piecesRoot == null || !bytesEq(root, f.piecesRoot)) continue;
|
||||
if (meta.fileHashes[fi] != null) return;
|
||||
var np = Std.int(Math.ceil(f.length
|
||||
/ meta.pieceLength));
|
||||
var np = Std.int(Math.ceil(f.length / meta.pieceLength));
|
||||
var pl = pendingLayers.get(fi);
|
||||
if (pl == null) {
|
||||
pl = {arr: [for (i in 0...np) null], got: 0};
|
||||
@ -585,8 +578,7 @@ class Torrent {
|
||||
var root = payload.sub(0, 32);
|
||||
for (fi in 0...meta.files.length) {
|
||||
var f = meta.files[fi];
|
||||
if (f.piecesRoot != null
|
||||
&& bytesEq(root, f.piecesRoot)) {
|
||||
if (f.piecesRoot != null && bytesEq(root, f.piecesRoot)) {
|
||||
hashReqNext.remove(fi);
|
||||
pendingLayers.remove(fi);
|
||||
return;
|
||||
@ -604,10 +596,8 @@ class Torrent {
|
||||
var np = Std.int(Math.ceil(f.length / meta.pieceLength));
|
||||
l = [];
|
||||
for (p in 0...np) {
|
||||
var size = Std.int(Math.min(meta.pieceLength,
|
||||
f.length - p * meta.pieceLength));
|
||||
l.push(meta.pieceRootV2(storage.read(
|
||||
f.offset + p * meta.pieceLength, size)));
|
||||
var size = Std.int(Math.min(meta.pieceLength, f.length - p * meta.pieceLength));
|
||||
l.push(meta.pieceRootV2(storage.read(f.offset + p * meta.pieceLength, size)));
|
||||
}
|
||||
layerCache.set(fi, l);
|
||||
return l;
|
||||
@ -620,13 +610,11 @@ class Torrent {
|
||||
t = [level];
|
||||
var depth = 0;
|
||||
while (level.length > 1) {
|
||||
var zero = MetaInfo.layerZero(pieceLayerBase()
|
||||
+ depth + 1);
|
||||
var zero = MetaInfo.layerZero(pieceLayerBase() + depth + 1);
|
||||
var next:Array<Bytes> = [];
|
||||
var i = 0;
|
||||
while (i < level.length) {
|
||||
var b = i + 1 < level.length
|
||||
? level[i + 1] : zero;
|
||||
var b = i + 1 < level.length ? level[i + 1] : zero;
|
||||
next.push(MetaInfo.hashPair(level[i], b));
|
||||
i += 2;
|
||||
}
|
||||
|
||||
@ -5,9 +5,7 @@ import leenkx.network.torrent.storage.Storage;
|
||||
import leenkx.network.torrent.storage.Storage.IStorage;
|
||||
|
||||
class TorrentClient {
|
||||
public static var defaultTrackers:Array<String> = [
|
||||
"wss://ws1.leenkx.com"
|
||||
];
|
||||
public static var defaultTrackers:Array<String> = [];
|
||||
|
||||
public static var defaultDownloadDir:String = null;
|
||||
public var downloadDir:String = null;
|
||||
@ -247,8 +245,7 @@ class TorrentClient {
|
||||
files.push({path: name, data: Bytes.ofString(Std.string(data))});
|
||||
}
|
||||
|
||||
return {meta: MetaInfo.create(name, files, trackers, opts),
|
||||
files: files};
|
||||
return {meta: MetaInfo.create(name, files, trackers, opts), files: files};
|
||||
}
|
||||
|
||||
public static function readFolder(path:String, ?base:String):Array<{path:String, data:Bytes}> {
|
||||
@ -259,8 +256,7 @@ class TorrentClient {
|
||||
root = root.substr(0, root.length - 1);
|
||||
}
|
||||
if (base == null) {
|
||||
var i = Std.int(Math.max(root.lastIndexOf("/"),
|
||||
root.lastIndexOf("\\")));
|
||||
var i = Std.int(Math.max(root.lastIndexOf("/"), root.lastIndexOf("\\")));
|
||||
base = i >= 0 ? root.substr(i + 1) : root;
|
||||
}
|
||||
var files:Array<{path:String, data:Bytes}> = [];
|
||||
@ -317,20 +313,79 @@ class TorrentClient {
|
||||
return t;
|
||||
}
|
||||
|
||||
public function remove(infoHashHex:String, ?deleteData:Bool):Void {
|
||||
var t = torrents.get(infoHashHex);
|
||||
if (t == null) {
|
||||
t = torrents.get("v2:" + infoHashHex);
|
||||
if (t != null) infoHashHex = "v2:" + infoHashHex;
|
||||
public function get(id:Dynamic):Torrent {
|
||||
if (Std.isOfType(id, Torrent)) return id;
|
||||
if (id == null) return null;
|
||||
var hex = Std.string(id);
|
||||
if (StringTools.startsWith(hex, "v2:")) {
|
||||
hex = hex.substr(3);
|
||||
}
|
||||
if (t != null) {
|
||||
t.destroy();
|
||||
if (deleteData) t.deleteData();
|
||||
torrents.remove(infoHashHex);
|
||||
var t = torrents.get(hex);
|
||||
if (t == null) t = torrents.get("v2:" + hex);
|
||||
if (t == null) {
|
||||
for (f in torrents) {
|
||||
if (f.infoHashHex == hex || f.infoHashV2Hex == hex || (f.infoHash != null && Crypto.toHex(f.infoHash) == hex)) {
|
||||
t = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public static function torrentIdFor(v:Dynamic):Dynamic {
|
||||
if (v == null) return null;
|
||||
if (Std.isOfType(v, haxe.io.Bytes)) return v;
|
||||
var s = Std.string(v);
|
||||
if (s.indexOf("magnet:") == 0) return s;
|
||||
if (s.indexOf("v2:") == 0) {
|
||||
var h = s.substr(3);
|
||||
return h.length == 64 ? "magnet:?xt=urn:btmh:1220" + h : s;
|
||||
}
|
||||
switch (s.length) {
|
||||
case 40 | 32:
|
||||
return "magnet:?xt=urn:btih:" + s;
|
||||
case 64:
|
||||
return "magnet:?xt=urn:btmh:1220" + s;
|
||||
case 68:
|
||||
return "magnet:?xt=urn:btmh:" + s;
|
||||
default:
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
static function mergeTrackers(trackers:Array<String>, urls:Array<String>):Void {
|
||||
public static function trackerUrls(v:Dynamic):Array<String> {
|
||||
if (v == null) return null;
|
||||
var items:Array<Dynamic> = Std.isOfType(v, Array)
|
||||
? (v:Array<Dynamic>) : [v];
|
||||
var out:Array<String> = [];
|
||||
for (item in items) {
|
||||
var u:Dynamic = null;
|
||||
if (!Std.isOfType(item, String)) {
|
||||
try {
|
||||
u = Reflect.field(item, "url");
|
||||
} catch(e:Dynamic) {}
|
||||
}
|
||||
var s = u != null ? Std.string(u) : Std.string(item);
|
||||
if (s != "" && s != "null") out.push(s);
|
||||
}
|
||||
return out.length > 0 ? out : null;
|
||||
}
|
||||
|
||||
public function remove(infoHashHex:String, ?deleteData:Bool):Void {
|
||||
var t = get(infoHashHex);
|
||||
if (t != null) {
|
||||
t.destroy();
|
||||
if (deleteData) t.deleteData();
|
||||
var key:String = null;
|
||||
for (k in torrents.keys()) {
|
||||
if (torrents.get(k) == t) { key = k; break; }
|
||||
}
|
||||
if (key != null) torrents.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public static function mergeTrackers(trackers:Array<String>, urls:Array<String>):Void {
|
||||
if (urls == null) return;
|
||||
for (u in urls) {
|
||||
if (u != null && Lambda.indexOf(trackers, u) < 0) {
|
||||
|
||||
@ -51,10 +51,12 @@ class RtcPeerPool {
|
||||
var rtcInitialized = false;
|
||||
#end
|
||||
|
||||
public static var defaultIceServers:Array<String> =
|
||||
["stun:stun.l.google.com:19302", "stun:global.stun.twilio.com:3478"];
|
||||
|
||||
public function new(?iceServers:Array<String>, ?channelLabel:String, unordered:Bool = false, maxRetransmits:Int = -1) {
|
||||
this.iceServers = iceServers != null ? iceServers
|
||||
: ["stun:stun.l.google.com:19302",
|
||||
"stun:global.stun.twilio.com:3478"];
|
||||
: defaultIceServers.copy();
|
||||
if (channelLabel != null) this.channelLabel = channelLabel;
|
||||
this.unordered = unordered;
|
||||
this.maxRetransmits = maxRetransmits;
|
||||
@ -72,8 +74,7 @@ class RtcPeerPool {
|
||||
}
|
||||
#end
|
||||
|
||||
var signaling = new RtcSignaling(trackerUrl, infoHashBinary,
|
||||
peerIdBinary);
|
||||
var signaling = new RtcSignaling(trackerUrl, infoHashBinary, peerIdBinary);
|
||||
signalings.push(signaling);
|
||||
signaling.statsProvider = statsProvider;
|
||||
signaling.onConnected = function() {
|
||||
@ -223,8 +224,7 @@ class RtcPeerPool {
|
||||
}
|
||||
};
|
||||
var dc = pc.createDataChannel(channelLabel,
|
||||
{ordered: !unordered,
|
||||
maxRetransmits: unordered ? maxRetransmits : null});
|
||||
{ordered: !unordered, maxRetransmits: unordered ? maxRetransmits : null});
|
||||
attachOfferChannel(offerIdHex, new DataChannelPeer(dc));
|
||||
var iceComplete = false;
|
||||
var iceTimer:haxe.Timer = null;
|
||||
@ -271,8 +271,7 @@ class RtcPeerPool {
|
||||
iceComplete = true;
|
||||
if (iceTimer != null) iceTimer.stop();
|
||||
if (!offerPeers.exists(offerIdHex)) return;
|
||||
sig.sendAnswer(peerIdHex, offerIdHex,
|
||||
pc.getLocalDescription());
|
||||
sig.sendAnswer(peerIdHex, offerIdHex, pc.getLocalDescription());
|
||||
};
|
||||
pc.onGatheringStateChange = function(state) {
|
||||
if (state == RTC_GATHERING_COMPLETE) sendAnswerSdp();
|
||||
@ -312,8 +311,7 @@ class RtcPeerPool {
|
||||
iceComplete = true;
|
||||
if (iceTimer != null) iceTimer.stop();
|
||||
if (!offerPeers.exists(offerIdHex)) return;
|
||||
sig.sendAnswer(peerIdHex, offerIdHex,
|
||||
RtcNative.getLocalDescription(pcId));
|
||||
sig.sendAnswer(peerIdHex, offerIdHex, RtcNative.getLocalDescription(pcId));
|
||||
};
|
||||
RtcNative.setGatheringStateCallback(pcId, function(state:Int) {
|
||||
if (state == RtcNative.RTC_GATHERING_COMPLETE) sendAnswerSdp();
|
||||
|
||||
@ -36,6 +36,10 @@ class DatachannelTransport implements ITransport {
|
||||
if (opts.announce != null && opts.announce.length > 0) {
|
||||
url = opts.announce[0];
|
||||
}
|
||||
if (url == null || url == "") {
|
||||
if (onError != null) onError("no announce tracker configured");
|
||||
return;
|
||||
}
|
||||
if (opts.iceServers != null) iceServers = opts.iceServers;
|
||||
pk = opts.pk != null ? opts.pk : "";
|
||||
ek = opts.ek != null ? opts.ek : "";
|
||||
|
||||
@ -48,7 +48,7 @@ class WebTorrentTransport implements ITransport {
|
||||
var blob:Dynamic = createBlob(identifier);
|
||||
var torrentOpts:Dynamic = {
|
||||
name: identifier,
|
||||
announce: opts.announce != null ? opts.announce : ["wss://ws1.leenkx.com"]
|
||||
announce: opts.announce != null ? opts.announce : leenkx.network.torrent.TorrentClient.defaultTrackers
|
||||
};
|
||||
if (opts.torrentOpts != null) {
|
||||
torrentOpts = js.lib.Object.assign(
|
||||
|
||||
@ -43,6 +43,10 @@ class WireTransport implements ITransport {
|
||||
if (opts.announce != null && opts.announce.length > 0) {
|
||||
url = opts.announce[0];
|
||||
}
|
||||
if (url == null || url == "") {
|
||||
if (onError != null) onError("no announce tracker configured");
|
||||
return;
|
||||
}
|
||||
if (opts.iceServers != null) iceServers = opts.iceServers;
|
||||
pk = opts.pk != null ? opts.pk : "";
|
||||
ek = opts.ek != null ? opts.ek : "";
|
||||
|
||||
Reference in New Issue
Block a user