forked from LeenkxTeam/LNXSDK
P2P Export - Nodes - Patch
This commit is contained in:
@ -1,30 +0,0 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class AddTorrentNode(LnxLogicTreeNode):
|
||||
"""Add Torrent"""
|
||||
bl_idname = 'LNAddTorrentNode'
|
||||
bl_label = 'Add Torrent'
|
||||
bl_description = 'Add a torrent file from the network'
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AddTorrentNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxStringSocket', 'Torrent')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Title')
|
||||
self.add_output('LnxDynamicSocket', 'Files')
|
||||
self.add_output('LnxNodeSocketAction', 'Done')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
AddTorrentNode.on_register()
|
||||
@ -4,19 +4,71 @@ class CreateLeenkxNode(LnxLogicTreeNode):
|
||||
"""Create Leenkx"""
|
||||
bl_idname = 'LNCreateLeenkxNode'
|
||||
bl_label = 'Create Leenkx'
|
||||
bl_description = 'Create Leenkx'
|
||||
bl_description = ('Open a Leenkx peer connection on the given swarm identifier')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[2:]:
|
||||
self.inputs.remove(socket)
|
||||
if (self.property0 == 'datachannel'
|
||||
and self.property2 != 'inherit'):
|
||||
self.add_input('LnxNodeSocketArray', 'ICE Servers')
|
||||
if self.property3 != 'inherit':
|
||||
self.add_input('LnxNodeSocketArray', 'Trackers')
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('wire', 'Wire', 'BitTorrent wire protocol transport (default)'),
|
||||
('datachannel', 'DataChannel', 'WebRTC data channels for browser/krom peers - shows the ICE Servers input')],
|
||||
name='Transport', default='wire', update=update_sockets)
|
||||
|
||||
property1: HaxeBoolProperty('property1',
|
||||
name='Gossip', description='Relay mode - forward messages to all connected peers', default=False)
|
||||
|
||||
property2: HaxeEnumProperty('property2',
|
||||
items=[('inherit', 'Inherit', 'Use the built-in STUN server list; no ICE Servers input'),
|
||||
('add', 'Add', 'Merge the ICE Servers input on top of the built-in STUN servers'),
|
||||
('override', 'Override', 'Replace the ICE server list with the ICE Servers input')],
|
||||
name='ICE Servers', default='inherit', update=update_sockets)
|
||||
|
||||
property3: HaxeEnumProperty('property3',
|
||||
items=[('inherit', 'Inherit', 'Use the project torrent tracker list; no Trackers input'),
|
||||
('add', 'Add', 'Merge the Trackers input on top of the project tracker list'),
|
||||
('override', 'Override', 'Replace the announce tracker list with the Trackers input')],
|
||||
name='Trackers', default='inherit', update=update_sockets)
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxStringSocket', 'Url', default_value="8001")
|
||||
self.add_input('LnxStringSocket', 'Channel', default_value='8001')
|
||||
if (self.property0 == 'datachannel'
|
||||
and self.property2 != 'inherit'):
|
||||
self.add_input('LnxNodeSocketArray', 'ICE Servers')
|
||||
if self.property3 != 'inherit':
|
||||
self.add_input('LnxNodeSocketArray', 'Trackers')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Connection')
|
||||
self.add_output('LnxDynamicSocket', 'ID')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, 'property1')
|
||||
if self.property0 == 'datachannel':
|
||||
layout.prop(self, 'property2')
|
||||
layout.prop(self, 'property3')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
|
||||
@ -5,7 +5,7 @@ class CreateTorrentNode(LnxLogicTreeNode):
|
||||
"""Create Torrent"""
|
||||
bl_idname = 'LNCreateTorrentNode'
|
||||
bl_label = 'Create Torrent'
|
||||
bl_description = 'Create a torrent file from the network'
|
||||
bl_description = ('Build a .torrent from content (file, files or folder)')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
@ -13,17 +13,67 @@ class CreateTorrentNode(LnxLogicTreeNode):
|
||||
super(CreateTorrentNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[1:]:
|
||||
self.inputs.remove(socket)
|
||||
self._add_data_inputs()
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
def _add_data_inputs(self):
|
||||
mode_sockets = {
|
||||
'file': ('LnxDynamicSocket', 'File (Bytes)', 'Content of the single file as Bytes'),
|
||||
'files': ('LnxNodeSocketArray', 'Files ({path, data})', 'Array of {path, data} objects'),
|
||||
'folder': ('LnxStringSocket', 'Folder Path', 'Folder read recursively for content (native targets only)'),
|
||||
}
|
||||
socket_type, label, desc = mode_sockets.get(self.property1, mode_sockets['file'])
|
||||
self.add_input(socket_type, label)
|
||||
self.add_input('LnxStringSocket', 'Name')
|
||||
self.add_input('LnxStringSocket', 'Comment')
|
||||
self.add_input('LnxStringSocket', 'Created By')
|
||||
self.add_input('LnxStringSocket', 'Source')
|
||||
self.add_input('LnxNodeSocketArray', 'Trackers')
|
||||
self.add_input('LnxBoolSocket', 'Private')
|
||||
self.add_input('LnxIntSocket', 'Piece Length')
|
||||
self.add_input('LnxNodeSocketArray', 'Web Seeds')
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('1', 'V1', 'BitTorrent v1 - SHA-1 piece list over one packed stream; works with every client'),
|
||||
('2', 'V2', 'BitTorrent v2 (BEP 52) - SHA-256 merkle tree per file, pieces aligned to file boundaries; needs modern peers'),
|
||||
('3', 'Hybrid', 'One .torrent with both v1 and v2 metadata - two infohashes (btih + btmh) over the same info dict')],
|
||||
name='Version', default='1')
|
||||
|
||||
property1: HaxeEnumProperty('property1',
|
||||
items=[('file', 'File', 'Single file: Data is a Bytes payload'),
|
||||
('files', 'Files', 'Multiple files: Data is an array of {path, data}'),
|
||||
('folder', 'Folder', 'Read a folder recursively (native targets only): Data is a folder path string')],
|
||||
name='Data', default='file', update=update_sockets)
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxDynamicSocket', 'Data')
|
||||
self._add_data_inputs()
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Torrent')
|
||||
self.add_output('LnxNodeSocketAction', 'Done')
|
||||
self.add_output('LnxDynamicSocket', 'Meta')
|
||||
self.add_output('LnxDynamicSocket', 'Torrent Bytes')
|
||||
self.add_output('LnxStringSocket', 'InfoHash')
|
||||
self.add_output('LnxStringSocket', 'Magnet')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, 'property1')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
CreateTorrentNode.on_register()
|
||||
CreateTorrentNode.on_register()
|
||||
|
||||
61
leenkx/blender/lnx/logicnode/custom/LN_create_tracker.py
Normal file
61
leenkx/blender/lnx/logicnode/custom/LN_create_tracker.py
Normal file
@ -0,0 +1,61 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class CreateTrackerNode(LnxLogicTreeNode):
|
||||
"""Create Tracker"""
|
||||
bl_idname = 'LNCreateTrackerNode'
|
||||
bl_label = 'Create Tracker Server'
|
||||
bl_description = ('Hosts a local tracker')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CreateTrackerNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[1:]:
|
||||
self.inputs.remove(socket)
|
||||
self._add_mode_inputs()
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
def _add_mode_inputs(self):
|
||||
self.add_input('LnxStringSocket', 'Host', default_value='127.0.0.1')
|
||||
self.add_input('LnxIntSocket', 'Port', default_value=6969)
|
||||
if self.property0 == 'wss':
|
||||
self.add_input('LnxStringSocket', 'Cert File')
|
||||
self.add_input('LnxStringSocket', 'Key File')
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('udp', 'UDP', 'UDP tracker (BEP 15, sys targets only)'),
|
||||
('http', 'HTTP', 'HTTP tracker (BEP 3)'),
|
||||
('ws', 'WS', 'Plain WebSocket tracker (local relay, WebTorrent/web peers)'),
|
||||
('wss', 'WSS', 'Secure WebSocket tracker (WebTorrent/web peers)')],
|
||||
name='Type', default='udp', update=update_sockets)
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self._add_mode_inputs()
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Tracker')
|
||||
self.add_output('LnxStringSocket', 'URL')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
CreateTrackerNode.on_register()
|
||||
76
leenkx/blender/lnx/logicnode/custom/LN_download_torrent.py
Normal file
76
leenkx/blender/lnx/logicnode/custom/LN_download_torrent.py
Normal file
@ -0,0 +1,76 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class DownloadTorrentNode(LnxLogicTreeNode):
|
||||
"""Download Torrent"""
|
||||
bl_idname = 'LNDownloadTorrentNode'
|
||||
bl_label = 'Download Torrent'
|
||||
bl_description = ('Add a torrent to a Leenkx connection and start downloading')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DownloadTorrentNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[2:]:
|
||||
self.inputs.remove(socket)
|
||||
self._add_id_inputs()
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
def _add_id_inputs(self):
|
||||
mode_sockets = {
|
||||
'magnet': ('LnxStringSocket', 'Magnet URI', 'Magnet URI (magnet:?xt=...)'),
|
||||
'id': ('LnxStringSocket', 'Infohash', '40-char v1 or 64-char v2 infohash hex'),
|
||||
'file': ('LnxDynamicSocket', 'Torrent File (Bytes)', '.torrent file bytes'),
|
||||
}
|
||||
socket_type, label, desc = mode_sockets.get(self.property0, mode_sockets['magnet'])
|
||||
self.add_input(socket_type, label)
|
||||
if self.property1 != 'inherit':
|
||||
self.add_input('LnxNodeSocketArray', 'Trackers')
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('magnet', 'Magnet', 'Magnet URI (magnet:?xt=...)'),
|
||||
('id', 'Infohash', '40-char v1 or 64-char v2 infohash hex'),
|
||||
('file', 'Torrent File', '.torrent file bytes')],
|
||||
name='Input', default='magnet', update=update_sockets)
|
||||
|
||||
property1: HaxeEnumProperty('property1',
|
||||
items=[('inherit', 'Inherit', 'Use the torrent\'s own trackers plus the connection\'s; no Trackers input'),
|
||||
('add', 'Add', 'Merge the Trackers input on top of the torrent\'s own trackers'),
|
||||
('override', 'Override', 'Replace all trackers with the Trackers input (torrent\'s own and connection defaults are dropped)')],
|
||||
name='Trackers', default='inherit', update=update_sockets)
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self._add_id_inputs()
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Torrent')
|
||||
self.add_output('LnxStringSocket', 'Name')
|
||||
self.add_output('LnxNodeSocketArray', 'Files')
|
||||
self.add_output('LnxNodeSocketAction', 'Done')
|
||||
self.add_output('LnxStringSocket', 'InfoHash')
|
||||
self.add_output('LnxStringSocket', 'Magnet')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, 'property1')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
DownloadTorrentNode.on_register()
|
||||
77
leenkx/blender/lnx/logicnode/custom/LN_get_torrent_file.py
Normal file
77
leenkx/blender/lnx/logicnode/custom/LN_get_torrent_file.py
Normal file
@ -0,0 +1,77 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class GetTorrentFileNode(LnxLogicTreeNode):
|
||||
"""Get Torrent File"""
|
||||
bl_idname = 'LNGetTorrentFileNode'
|
||||
bl_label = 'Get Torrent File'
|
||||
bl_description = ('Find one file inside a torrent and read its '
|
||||
'stored bytes (webtorrent torrent.files.find + '
|
||||
'file.arrayBuffer). Match By selects how the '
|
||||
'Match input is interpreted: index, exact file '
|
||||
'name, exact path, or extension')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(GetTorrentFileNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[3:]:
|
||||
self.inputs.remove(socket)
|
||||
self._add_match_input()
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
def _add_match_input(self):
|
||||
match_sockets = {
|
||||
'index': ('LnxIntSocket', 'Index', 'Position in the torrent file list'),
|
||||
'name': ('LnxStringSocket', 'Name', 'Exact file name, e.g. movie.mp4'),
|
||||
'path': ('LnxStringSocket', 'Path', 'Exact path inside the torrent, e.g. docs/readme.txt'),
|
||||
'ext': ('LnxStringSocket', 'Extension', 'File extension like mp4 or .mp4; first matching file wins'),
|
||||
}
|
||||
socket_type, label, desc = match_sockets.get(self.property0, match_sockets['name'])
|
||||
self.add_input(socket_type, label)
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('index', 'Index', 'Position in the torrent file list; Match is an int'),
|
||||
('name', 'Name', 'Exact file name; Match is a string like movie.mp4'),
|
||||
('path', 'Path', 'Exact path inside the torrent; Match is a string like docs/readme.txt'),
|
||||
('ext', 'Extension', 'First file whose name ends with the extension; Match is mp4 or .mp4')],
|
||||
name='Match By', default='name', update=update_sockets)
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxDynamicSocket', 'Torrent')
|
||||
self._add_match_input()
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'File')
|
||||
self.add_output('LnxStringSocket', 'Name')
|
||||
self.add_output('LnxStringSocket', 'Path')
|
||||
self.add_output('LnxFloatSocket', 'Size')
|
||||
self.add_output('LnxStringSocket', 'Type')
|
||||
self.add_output('LnxDynamicSocket', 'Data')
|
||||
self.add_output('LnxBoolSocket', 'Found')
|
||||
self.add_output('LnxFloatSocket', 'Downloaded')
|
||||
self.add_output('LnxFloatSocket', 'Progress')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
GetTorrentFileNode.on_register()
|
||||
@ -5,63 +5,40 @@ class LeenkxCloseConnectionNode(LnxLogicTreeNode):
|
||||
"""Close connection on the network"""
|
||||
bl_idname = 'LNLeenkxCloseConnectionNode'
|
||||
bl_label = 'Close Leenkx Connection'
|
||||
bl_description = ('Tear down a Leenkx connection, or drop a single peer from it')
|
||||
lnx_version = 1
|
||||
lnx_category = 'Leenkx'
|
||||
ind = 2
|
||||
|
||||
@staticmethod
|
||||
def get_enum_id_value(obj, prop_name, value):
|
||||
return obj.bl_rna.properties[prop_name].enum_items[value].identifier
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[2:]:
|
||||
self.inputs.remove(socket)
|
||||
if self.property0 == 'peer':
|
||||
self.add_input('LnxStringSocket', 'ID')
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
@staticmethod
|
||||
def get_count_in(type_name):
|
||||
return {
|
||||
'client': 0,
|
||||
'peer': 1
|
||||
}.get(type_name, 0)
|
||||
|
||||
def get_enum(self):
|
||||
return self.get('property0', 0)
|
||||
|
||||
def set_enum(self, value):
|
||||
# Checking the selection of each type
|
||||
select_current = self.get_enum_id_value(self, 'property0', value)
|
||||
select_prev = self.property0
|
||||
|
||||
#Check if type changed
|
||||
if select_prev != select_current:
|
||||
|
||||
for i in self.inputs:
|
||||
self.inputs.remove(i)
|
||||
|
||||
# Arguements for type Host
|
||||
if (self.get_count_in(select_current) == 0):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxStringSocket', 'Url')
|
||||
|
||||
# Arguements for type Client
|
||||
if (self.get_count_in(select_current) == 1):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxStringSocket', 'ID')
|
||||
|
||||
self['property0'] = value
|
||||
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property1',
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items = [('client', 'Leenkx Client', 'Close the Leenkx Client connection on the network'),
|
||||
('peer', 'Single Peer', 'Close a Peer connection on network')],
|
||||
('peer', 'Single Peer', 'Drop a peer from the connection (forgets its address; it can rejoin on a new handshake)')],
|
||||
name='', default='client',
|
||||
set=set_enum,
|
||||
get=get_enum)
|
||||
update=update_sockets)
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxStringSocket', 'Url')
|
||||
if self.property0 == 'peer':
|
||||
self.add_input('LnxStringSocket', 'ID')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
|
||||
@ -9,84 +9,26 @@ class LeenkxEventNode(LnxLogicTreeNode):
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
@staticmethod
|
||||
def get_enum_id_value(obj, prop_name, value):
|
||||
return obj.bl_rna.properties[prop_name].enum_items[value].identifier
|
||||
|
||||
@staticmethod
|
||||
def get_count_in(type_name):
|
||||
return {
|
||||
'client': 0,
|
||||
'host': 1,
|
||||
'securehost': 2
|
||||
}.get(type_name, 0)
|
||||
|
||||
def get_enum(self):
|
||||
return self.get('property0', 0)
|
||||
|
||||
def set_enum(self, value):
|
||||
# Checking the selection of each type
|
||||
select_current = self.get_enum_id_value(self, 'property0', value)
|
||||
select_prev = self.property0
|
||||
|
||||
#Check if type changed
|
||||
if select_prev != select_current:
|
||||
|
||||
for i in self.inputs:
|
||||
self.inputs.remove(i)
|
||||
|
||||
# Arguements for type Client
|
||||
if (self.get_count_in(select_current) == 0):
|
||||
self.add_input('LnxStringSocket', 'Url', default_value="8001")
|
||||
|
||||
|
||||
# Arguements for type Host
|
||||
if (self.get_count_in(select_current) == 1):
|
||||
self.add_input('LnxStringSocket', 'Domain', default_value="127.0.0.1")
|
||||
self.add_input('LnxIntSocket', 'Port', default_value=8001)
|
||||
|
||||
|
||||
# Arguements for type Secure Host
|
||||
if (self.get_count_in(select_current) == 2):
|
||||
self.add_input('LnxStringSocket', 'Domain', default_value="127.0.0.1")
|
||||
self.add_input('LnxIntSocket', 'Port', default_value=8001)
|
||||
|
||||
|
||||
self['property0'] = value
|
||||
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('client', 'Client', 'Network client Event listener'),
|
||||
('host', 'Host', 'Network host Event listener'),
|
||||
('securehost', 'Secure Host', 'Network secure host Event listener')],
|
||||
name='',
|
||||
default='client',
|
||||
set=set_enum,
|
||||
get=get_enum)
|
||||
|
||||
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
items = [('onopen', 'OnOpen', 'Listens to onOpen event'),
|
||||
('onmessage', 'OnMessage', 'Listens to onMessage event'),
|
||||
('onerror', 'OnError', 'Listens to onError event'),
|
||||
('onclose', 'OnClose', 'Listens to onClose event'),
|
||||
('onseen', 'OnSeen', 'Listens to onClose event'),
|
||||
('onserver', 'OnServer', 'Listens to onClose event'),
|
||||
('onconnections', 'OnConnections', 'Listens to onClose event'),
|
||||
('onping', 'OnPing', 'Listens to onClose event'),
|
||||
('onleft', 'OnLeft', 'Listens to onClose event'),
|
||||
('ontimeout', 'OnTimeout', 'Listens to onClose event'),
|
||||
('onrpc', 'OnRpc', 'Listens to onClose event'),
|
||||
('onrpcresponse', 'OnRpcResponse', 'Listens to onClose event'),
|
||||
('onwireleft', 'OnWireLeft', 'Listens to onClose event'),
|
||||
('onwireseen', 'OnWireSeen', 'Listens to onClose event'),
|
||||
('ontorrent', 'OnTorrent', 'Listens to onClose event'),
|
||||
('ontracker', 'OnTracker', 'Listens to onClose event'),
|
||||
('onannounce', 'OnAnnounce', 'Listens to onClose event')],
|
||||
name='',
|
||||
default='onopen')
|
||||
property1: HaxeEnumProperty('property1',
|
||||
items = [('onopen', 'OnOpen', 'The connection to the server is open'),
|
||||
('onmessage', 'OnMessage', 'A message arrived; ID is the sender peer id, Data the payload'),
|
||||
('onerror', 'OnError', 'A connection error occurred'),
|
||||
('onclose', 'OnClose', 'The connection was closed'),
|
||||
('onseen', 'OnSeen', 'A peer was discovered; ID is the peer id'),
|
||||
('onserver', 'OnServer', 'The signaling server responded'),
|
||||
('onconnections', 'OnConnections', 'The server sent the peer list; Data is the connection list'),
|
||||
('onping', 'OnPing', 'Heartbeat ping roundtrip completed'),
|
||||
('onleft', 'OnLeft', 'A peer left; ID is the peer id'),
|
||||
('ontimeout', 'OnTimeout', 'A handshake timed out'),
|
||||
('onwireleft', 'OnWireLeft', 'A BitTorrent wire peer disconnected; ID is the peer id'),
|
||||
('onwireseen', 'OnWireSeen', 'A BitTorrent wire peer connected; ID is the peer id'),
|
||||
('ontorrent', 'OnTorrent', 'Torrent activity on the connection; Data is the torrent'),
|
||||
('ontorrentadded', 'OnTorrentAdded', 'A torrent registered on the connection; Data is the Torrent handle'),
|
||||
('ontracker', 'OnTracker', 'A tracker event on the connection'),
|
||||
('onannounce', 'OnAnnounce', 'A tracker announce completed'),
|
||||
('ontorrentdone', 'OnTorrentDone', 'A torrent finished downloading; Data is the torrent'),
|
||||
('onload', 'OnLoad', 'The connection was registered; fires once at startup')],
|
||||
name='', default='onopen')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LeenkxEventNode, self).__init__(*args, **kwargs)
|
||||
@ -95,7 +37,7 @@ class LeenkxEventNode(LnxLogicTreeNode):
|
||||
|
||||
def lnx_init(self, context):
|
||||
#self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxStringSocket', 'Url', default_value="ws://127.0.0.1:8001")
|
||||
self.add_input('LnxStringSocket', 'Channel', default_value='8001')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'ID')
|
||||
@ -103,7 +45,6 @@ class LeenkxEventNode(LnxLogicTreeNode):
|
||||
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, 'property1')
|
||||
|
||||
def register():
|
||||
|
||||
@ -9,16 +9,15 @@ class LeenkxMessageParserNode(LnxLogicTreeNode):
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('string', 'String', 'Event for a string over the network'),
|
||||
('vector', 'Vector', 'Event for a vector over the network'),
|
||||
('float', 'Float', 'Event for a float over the network'),
|
||||
('integer', 'Integer', 'Event for an integer over the network'),
|
||||
('boolean', 'Boolean', 'Event for a boolean over the network'),
|
||||
('transform', 'Transform', 'Event for a transform over the network'),
|
||||
('rotation', 'Rotation', 'Event for a rotation over the network')],
|
||||
name='', default='string')
|
||||
property0: HaxeEnumProperty('property0', items=[
|
||||
('string', 'String', 'Parse the message as a string'),
|
||||
('vector', 'Vector', 'Parse the message as a vector (Vec4)'),
|
||||
('float', 'Float', 'Parse the message as a float'),
|
||||
('integer', 'Integer', 'Parse the message as an integer'),
|
||||
('boolean', 'Boolean', 'Parse the message as a boolean'),
|
||||
('transform', 'Transform', 'Parse the message as a transform (Mat4)'),
|
||||
('rotation', 'Rotation', 'Parse the message as a rotation (Quat)')
|
||||
], name='', default='string')
|
||||
|
||||
|
||||
def lnx_init(self, context):
|
||||
|
||||
@ -9,77 +9,55 @@ class LeenkxSendMessageNode(LnxLogicTreeNode):
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
@staticmethod
|
||||
def get_enum_id_value(obj, prop_name, value):
|
||||
return obj.bl_rna.properties[prop_name].enum_items[value].identifier
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
send_all = True
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
if socket.name == 'Send All':
|
||||
send_all = socket.default_value_raw
|
||||
for socket in self.inputs[3:]:
|
||||
self.inputs.remove(socket)
|
||||
self._add_data_inputs(send_all)
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
@staticmethod
|
||||
def get_count_in(type_name):
|
||||
return {
|
||||
'client': 0,
|
||||
'host': 1,
|
||||
'securehost': 2
|
||||
}.get(type_name, 0)
|
||||
def _add_data_inputs(self, send_all=True):
|
||||
data_sockets = {
|
||||
'string': ('LnxStringSocket', 'String payload to send'),
|
||||
'vector': ('LnxVectorSocket', 'Vector payload to send'),
|
||||
'float': ('LnxFloatSocket', 'Float payload to send'),
|
||||
'integer': ('LnxIntSocket', 'Integer payload to send'),
|
||||
'boolean': ('LnxBoolSocket', 'Boolean payload to send'),
|
||||
'transform': ('LnxDynamicSocket', 'Transform (Mat4) payload to send'),
|
||||
'rotation': ('LnxRotationSocket', 'Rotation (Quat) payload to send'),
|
||||
}
|
||||
socket_type, desc = data_sockets.get(self.property1, data_sockets['string'])
|
||||
self.add_input(socket_type, 'Data')
|
||||
self.add_input('LnxBoolSocket', 'Send All', default_value=send_all)
|
||||
if not send_all:
|
||||
self._add_id_input()
|
||||
|
||||
def get_enum(self):
|
||||
return self.get('property0', 0)
|
||||
def _add_id_input(self):
|
||||
self.add_input('LnxStringSocket', 'ID')
|
||||
|
||||
def set_enum(self, value):
|
||||
# Checking the selection of each type
|
||||
select_current = self.get_enum_id_value(self, 'property0', value)
|
||||
select_prev = self.property0
|
||||
def on_socket_val_update(self, context, socket):
|
||||
if socket.name == 'Send All':
|
||||
if (len(self.inputs) > 5
|
||||
and self.inputs[5].name == 'ID'):
|
||||
self.inputs.remove(self.inputs[5])
|
||||
if not socket.default_value_raw:
|
||||
self._add_id_input()
|
||||
super().on_socket_val_update(context, socket)
|
||||
|
||||
#Check if type changed
|
||||
if select_prev != select_current:
|
||||
|
||||
for i in self.inputs:
|
||||
self.inputs.remove(i)
|
||||
|
||||
# Arguements for type Client
|
||||
if (self.get_count_in(select_current) == 0):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxStringSocket', 'API')
|
||||
self.add_input('LnxDynamicSocket', 'Data')
|
||||
self.add_input('LnxStringSocket', 'ID')
|
||||
self.add_input('LnxBoolSocket', 'Send All')
|
||||
|
||||
# Arguements for type Host
|
||||
if (self.get_count_in(select_current) == 1):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxStringSocket', 'API')
|
||||
self.add_input('LnxDynamicSocket', 'Data')
|
||||
self.add_input('LnxStringSocket', 'ID')
|
||||
self.add_input('LnxBoolSocket', 'Send All')
|
||||
|
||||
|
||||
# Arguements for type Secure Host
|
||||
if (self.get_count_in(select_current) == 2):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxStringSocket', 'API')
|
||||
self.add_input('LnxDynamicSocket', 'Data')
|
||||
self.add_input('LnxStringSocket', 'ID')
|
||||
self.add_input('LnxBoolSocket', 'Send All')
|
||||
|
||||
|
||||
self['property0'] = value
|
||||
|
||||
|
||||
property0: HaxeEnumProperty(
|
||||
'property0',
|
||||
items = [('client', 'Client', 'Network client Event listener'),
|
||||
('host', 'Host', 'Network host Event listener'),
|
||||
('securehost', 'Secure Host', 'Network secure host Event listener')],
|
||||
name='',
|
||||
default='client',
|
||||
set=set_enum,
|
||||
get=get_enum)
|
||||
|
||||
|
||||
property1: HaxeEnumProperty(
|
||||
'property1',
|
||||
property1: HaxeEnumProperty('property1',
|
||||
items = [('string', 'String', 'Send a string over the network to one or all of the clients'),
|
||||
('vector', 'Vector', 'Send a vector over the network to one or all of the clients'),
|
||||
('float', 'Float', 'Send a float over the network to one or all of the clients'),
|
||||
@ -87,8 +65,12 @@ class LeenkxSendMessageNode(LnxLogicTreeNode):
|
||||
('boolean', 'Boolean', 'Send a boolean over the network to one or all of the clients'),
|
||||
('transform', 'Transform', 'Send a transform over the network to one or all of the clients'),
|
||||
('rotation', 'Rotation', 'Send a rotation over the network to one or all of the clients')],
|
||||
name='',
|
||||
default='string')
|
||||
name='', default='string', update=update_sockets)
|
||||
|
||||
property2: HaxeBoolProperty('property2',
|
||||
name='Encrypted',
|
||||
description='Use full encryption protocol (signing, bencode, box encryption). Disable for fast raw message mode',
|
||||
default=False)
|
||||
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -100,17 +82,15 @@ class LeenkxSendMessageNode(LnxLogicTreeNode):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxStringSocket', 'API')
|
||||
self.add_input('LnxDynamicSocket', 'Data')
|
||||
self.add_input('LnxStringSocket', 'ID')
|
||||
self.add_input('LnxBoolSocket', 'Send All')
|
||||
|
||||
self._add_data_inputs()
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
|
||||
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
layout.prop(self, 'property1')
|
||||
layout.prop(self, 'property2')
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
|
||||
68
leenkx/blender/lnx/logicnode/custom/LN_parse_torrent.py
Normal file
68
leenkx/blender/lnx/logicnode/custom/LN_parse_torrent.py
Normal file
@ -0,0 +1,68 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class ParseTorrentNode(LnxLogicTreeNode):
|
||||
"""Parse Torrent"""
|
||||
bl_idname = 'LNParseTorrentNode'
|
||||
bl_label = 'Parse Torrent'
|
||||
bl_description = ('Parse a torrent id without joining a swarm')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ParseTorrentNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[1:]:
|
||||
self.inputs.remove(socket)
|
||||
self._add_id_input()
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
def _add_id_input(self):
|
||||
mode_sockets = {
|
||||
'magnet': ('LnxStringSocket', 'Magnet URI', 'Magnet URI (magnet:?xt=...)'),
|
||||
'id': ('LnxStringSocket', 'Infohash', '40-char v1 or 64-char v2 infohash hex'),
|
||||
'file': ('LnxDynamicSocket', 'Torrent File (Bytes)', '.torrent file bytes'),
|
||||
}
|
||||
socket_type, label, desc = mode_sockets.get(self.property0, mode_sockets['magnet'])
|
||||
self.add_input(socket_type, label)
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('magnet', 'Magnet', 'Magnet URI (magnet:?xt=...)'),
|
||||
('id', 'Infohash', '40-char v1 or 64-char v2 infohash hex'),
|
||||
('file', 'Torrent File', '.torrent file bytes')],
|
||||
name='Input', default='magnet', update=update_sockets)
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self._add_id_input()
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Meta')
|
||||
self.add_output('LnxStringSocket', 'InfoHash')
|
||||
self.add_output('LnxStringSocket', 'Name')
|
||||
self.add_output('LnxNodeSocketArray', 'Trackers')
|
||||
self.add_output('LnxNodeSocketArray', 'Web Seeds')
|
||||
self.add_output('LnxNodeSocketArray', 'Files')
|
||||
self.add_output('LnxFloatSocket', 'Total Size')
|
||||
self.add_output('LnxDynamicSocket', 'Torrent Bytes')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
ParseTorrentNode.on_register()
|
||||
@ -17,12 +17,14 @@ class SeedTorrentNode(LnxLogicTreeNode):
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxDynamicSocket', 'Opts [Map]')
|
||||
self.add_input('LnxDynamicSocket', 'Torrent')
|
||||
self.add_input('LnxDynamicSocket', 'Data')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Torrent')
|
||||
self.add_output('LnxNodeSocketAction', 'Done')
|
||||
self.add_output('LnxStringSocket', 'InfoHash')
|
||||
self.add_output('LnxStringSocket', 'Magnet')
|
||||
|
||||
|
||||
def register():
|
||||
|
||||
75
leenkx/blender/lnx/logicnode/custom/LN_set_trackers.py
Normal file
75
leenkx/blender/lnx/logicnode/custom/LN_set_trackers.py
Normal file
@ -0,0 +1,75 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class SetTrackersNode(LnxLogicTreeNode):
|
||||
"""Set Trackers"""
|
||||
bl_idname = 'LNSetTrackersNode'
|
||||
bl_label = 'Set Trackers'
|
||||
bl_description = ('Add/Override edit the tracker announce list of a live torrent')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
tracker_props = {
|
||||
'interval': ('LnxIntSocket', 'Interval'),
|
||||
'port': ('LnxIntSocket', 'Port'),
|
||||
'key': ('LnxIntSocket', 'Key'),
|
||||
'numwant': ('LnxIntSocket', 'Num Want'),
|
||||
'trackerId': ('LnxStringSocket', 'Tracker ID'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SetTrackersNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def update_sockets(self, context):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[1:]:
|
||||
self.inputs.remove(socket)
|
||||
self._add_target_inputs()
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
def _add_target_inputs(self):
|
||||
if self.property0 in ('add', 'override'):
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxDynamicSocket', 'Torrent')
|
||||
self.add_input('LnxNodeSocketArray', 'Trackers')
|
||||
else:
|
||||
self.add_input('LnxDynamicSocket', 'Tracker')
|
||||
socket_type, label = self.tracker_props.get(
|
||||
self.property0, self.tracker_props['interval'])
|
||||
self.add_input(socket_type, label)
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('add', 'Add', 'Merge the Trackers input on top of the existing announce list'),
|
||||
('override', 'Override', 'Replace the announce list entirely; running tracker connections are restarted'),
|
||||
('interval', 'Interval', 'Announce interval in seconds'),
|
||||
('port', 'Port', 'Listening port reported to the tracker'),
|
||||
('key', 'Key', 'Session key sent with announces'),
|
||||
('numwant', 'Num Want', 'Number of peers requested per announce'),
|
||||
('trackerId', 'Tracker ID', 'Tracker id echoed back by the tracker')],
|
||||
name='Property', default='add', update=update_sockets)
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self._add_target_inputs()
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Target')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
SetTrackersNode.on_register()
|
||||
@ -0,0 +1,31 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class TorrentClientInfoNode(LnxLogicTreeNode):
|
||||
"""Torrent Client Info"""
|
||||
bl_idname = 'LNTorrentClientInfoNode'
|
||||
bl_label = 'Connection Torrents'
|
||||
bl_description = ('Aggregate stats for the torrent client attached')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TorrentClientInfoNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxNodeSocketArray', 'Torrents')
|
||||
self.add_output('LnxIntSocket', 'Count')
|
||||
self.add_output('LnxFloatSocket', 'Down Rate')
|
||||
self.add_output('LnxFloatSocket', 'Up Rate')
|
||||
self.add_output('LnxFloatSocket', 'Progress')
|
||||
self.add_output('LnxFloatSocket', 'Ratio')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
TorrentClientInfoNode.on_register()
|
||||
71
leenkx/blender/lnx/logicnode/custom/LN_torrent_control.py
Normal file
71
leenkx/blender/lnx/logicnode/custom/LN_torrent_control.py
Normal file
@ -0,0 +1,71 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class TorrentControlNode(LnxLogicTreeNode):
|
||||
"""Torrent Control"""
|
||||
bl_idname = 'LNTorrentControlNode'
|
||||
bl_label = 'Torrent Control'
|
||||
bl_description = ('Start, stop, remove or prioritize a torrent.')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TorrentControlNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('start', 'Start', 'Start or resume the torrent session'),
|
||||
('stop', 'Stop', 'Pause the torrent (announces stopped to trackers); it stays registered and can be started again'),
|
||||
('remove', 'Remove', 'Destroy the torrent and remove it from the client'),
|
||||
('remove-data', 'Remove + Data', 'Destroy the torrent and delete the stored content bytes'),
|
||||
('select', 'Select', 'Prioritize a piece range: File handle or Start/End bytes, Priority optional (webtorrent torrent.select)'),
|
||||
('deselect', 'Deselect', 'Drop a priority selection, back to normal order'),
|
||||
('critical', 'Critical', 'Top-priority selection for streaming seeks'),
|
||||
('add-peer', 'Add Peer', 'Connect to a peer directly; Address is host:port (sys/Krom targets only)'),
|
||||
('add-web-seed', 'Add Web Seed', 'Register a BEP 19 webseed; Address is an http(s) URL, fills pieces when peers can\'t serve them')],
|
||||
name='Action', default='start',
|
||||
update=lambda self, context: self._rebuild_inputs())
|
||||
|
||||
def _rebuild_inputs(self):
|
||||
if not self.inputs:
|
||||
return
|
||||
links = {}
|
||||
for socket in self.inputs:
|
||||
for link in socket.links:
|
||||
links.setdefault(socket.name, []).append(
|
||||
(link.from_node, link.from_socket))
|
||||
for socket in self.inputs[3:]:
|
||||
self.inputs.remove(socket)
|
||||
self._add_action_inputs()
|
||||
tree = self.id_data
|
||||
for socket in self.inputs:
|
||||
if socket.name in links:
|
||||
for from_node, from_socket in links[socket.name]:
|
||||
tree.links.new(from_socket, socket)
|
||||
|
||||
def _add_action_inputs(self):
|
||||
if self.property0 in ('select', 'deselect', 'critical'):
|
||||
self.add_input('LnxDynamicSocket', 'File')
|
||||
self.add_input('LnxIntSocket', 'Start')
|
||||
self.add_input('LnxIntSocket', 'End')
|
||||
self.add_input('LnxIntSocket', 'Priority')
|
||||
elif self.property0 == 'add-peer':
|
||||
self.add_input('LnxStringSocket', 'Address')
|
||||
elif self.property0 == 'add-web-seed':
|
||||
self.add_input('LnxStringSocket', 'Address')
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxDynamicSocket', 'Torrent')
|
||||
self._add_action_inputs()
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
TorrentControlNode.on_register()
|
||||
40
leenkx/blender/lnx/logicnode/custom/LN_torrent_event.py
Normal file
40
leenkx/blender/lnx/logicnode/custom/LN_torrent_event.py
Normal file
@ -0,0 +1,40 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class OnTorrentEventNode(LnxLogicTreeNode):
|
||||
"""On Torrent Event"""
|
||||
bl_idname = 'LNOnTorrentEventNode'
|
||||
bl_label = 'On Torrent Event'
|
||||
bl_description = ('Fires when the selected torrent event happens ')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(OnTorrentEventNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
property0: HaxeEnumProperty('property0',
|
||||
items=[('ready', 'Ready', 'Metainfo is known; fires immediately if already ready'),
|
||||
('piece', 'Piece', 'A piece finished downloading; Value is the piece index'),
|
||||
('wire', 'Wire', 'A peer connected; Value is the WireProtocol'),
|
||||
('metadata', 'Metadata', 'ut_metadata fetch completed; Value is the MetaInfo'),
|
||||
('done', 'Done', 'All pieces are downloaded'),
|
||||
('error', 'Error', 'Torrent failed; Value is the error string')],
|
||||
name='Event', default='done')
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxDynamicSocket', 'Torrent')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxDynamicSocket', 'Torrent')
|
||||
self.add_output('LnxDynamicSocket', 'Value')
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
layout.prop(self, 'property0')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
OnTorrentEventNode.on_register()
|
||||
46
leenkx/blender/lnx/logicnode/custom/LN_torrent_info.py
Normal file
46
leenkx/blender/lnx/logicnode/custom/LN_torrent_info.py
Normal file
@ -0,0 +1,46 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
|
||||
class TorrentInfoNode(LnxLogicTreeNode):
|
||||
"""Torrent Info"""
|
||||
bl_idname = 'LNTorrentInfoNode'
|
||||
bl_label = 'Torrent Info'
|
||||
bl_description = ('Read the state of a torrent: infohash, name, peer count, progress, transfer totals, magnet URI')
|
||||
lnx_category = 'Leenkx'
|
||||
lnx_version = 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TorrentInfoNode, self).__init__(*args, **kwargs)
|
||||
array_nodes[str(id(self))] = self
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketAction', 'In')
|
||||
self.add_input('LnxDynamicSocket', 'Connection')
|
||||
self.add_input('LnxDynamicSocket', 'Torrent')
|
||||
|
||||
self.add_output('LnxNodeSocketAction', 'Out')
|
||||
self.add_output('LnxStringSocket', 'InfoHash')
|
||||
self.add_output('LnxStringSocket', 'Name')
|
||||
self.add_output('LnxIntSocket', 'Peers')
|
||||
self.add_output('LnxFloatSocket', 'Progress')
|
||||
self.add_output('LnxFloatSocket', 'Downloaded')
|
||||
self.add_output('LnxFloatSocket', 'Uploaded')
|
||||
self.add_output('LnxBoolSocket', 'Done')
|
||||
self.add_output('LnxStringSocket', 'Magnet')
|
||||
self.add_output('LnxNodeSocketArray', 'Files')
|
||||
self.add_output('LnxIntSocket', 'Num Pieces')
|
||||
self.add_output('LnxIntSocket', 'Piece Length')
|
||||
self.add_output('LnxFloatSocket', 'Total Size')
|
||||
self.add_output('LnxStringSocket', 'Comment')
|
||||
self.add_output('LnxStringSocket', 'Created By')
|
||||
self.add_output('LnxIntSocket', 'Version')
|
||||
self.add_output('LnxStringSocket', 'InfoHash2')
|
||||
self.add_output('LnxFloatSocket', 'Down Rate')
|
||||
self.add_output('LnxFloatSocket', 'Up Rate')
|
||||
self.add_output('LnxBoolSocket', 'Stopped')
|
||||
self.add_output('LnxDynamicSocket', 'Torrent')
|
||||
|
||||
|
||||
def register():
|
||||
add_category('Leenkx', icon='ORIENTATION_CURSOR')
|
||||
TorrentInfoNode.on_register()
|
||||
Reference in New Issue
Block a user