From a5c52132fe42daed86ad5e7206e434f89d6d09bd Mon Sep 17 00:00:00 2001 From: Kai Vogelgesang Date: Wed, 16 Oct 2019 23:40:32 +0200 Subject: [PATCH] Init --- .gitignore | 217 ++++++++++++++++++ src/Proto/Layers/DMPLayer.py | 57 +++++ src/Proto/Layers/DataPacketFramingLayer.py | 66 ++++++ src/Proto/Layers/RootLayer.py | 51 ++++ .../SynchronizationPacketFramingLayer.py | 41 ++++ src/Proto/Layers/UniverseDiscoveryLayer.py | 58 +++++ .../UniverseDiscoveryPacketFramingLayer.py | 39 ++++ src/Proto/Layers/__init__.py | 8 + .../__pycache__/DMPLayer.cpython-37.pyc | Bin 0 -> 1629 bytes .../DataPacketFramingLayer.cpython-37.pyc | Bin 0 -> 2099 bytes .../__pycache__/RootLayer.cpython-37.pyc | Bin 0 -> 1541 bytes ...onizationPacketFramingLayer.cpython-37.pyc | Bin 0 -> 1464 bytes .../UniverseDiscoveryLayer.cpython-37.pyc | Bin 0 -> 1758 bytes ...DiscoveryPacketFramingLayer.cpython-37.pyc | Bin 0 -> 1436 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 406 bytes src/Proto/Packets/DataPacket.py | 49 ++++ src/Proto/Packets/Parser.py | 66 ++++++ src/Proto/Packets/SynchronizationPacket.py | 31 +++ src/Proto/Packets/UniverseDiscoveryPacket.py | 46 ++++ src/Proto/Packets/__init__.py | 5 + .../__pycache__/DataPacket.cpython-37.pyc | Bin 0 -> 1734 bytes .../Packets/__pycache__/Parser.cpython-37.pyc | Bin 0 -> 1330 bytes .../SynchronizationPacket.cpython-37.pyc | Bin 0 -> 1102 bytes .../UniverseDiscoveryPacket.cpython-37.pyc | Bin 0 -> 1696 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 306 bytes src/Proto/Vector.py | 15 ++ src/Proto/__init__.py | 0 src/Proto/__pycache__/Vector.cpython-37.pyc | Bin 0 -> 633 bytes src/Proto/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 132 bytes src/Proto/__pycache__/util.cpython-37.pyc | Bin 0 -> 303 bytes src/Proto/util.py | 2 + 31 files changed, 751 insertions(+) create mode 100644 .gitignore create mode 100644 src/Proto/Layers/DMPLayer.py create mode 100644 src/Proto/Layers/DataPacketFramingLayer.py create mode 100644 src/Proto/Layers/RootLayer.py create mode 100644 src/Proto/Layers/SynchronizationPacketFramingLayer.py create mode 100644 src/Proto/Layers/UniverseDiscoveryLayer.py create mode 100644 src/Proto/Layers/UniverseDiscoveryPacketFramingLayer.py create mode 100644 src/Proto/Layers/__init__.py create mode 100644 src/Proto/Layers/__pycache__/DMPLayer.cpython-37.pyc create mode 100644 src/Proto/Layers/__pycache__/DataPacketFramingLayer.cpython-37.pyc create mode 100644 src/Proto/Layers/__pycache__/RootLayer.cpython-37.pyc create mode 100644 src/Proto/Layers/__pycache__/SynchronizationPacketFramingLayer.cpython-37.pyc create mode 100644 src/Proto/Layers/__pycache__/UniverseDiscoveryLayer.cpython-37.pyc create mode 100644 src/Proto/Layers/__pycache__/UniverseDiscoveryPacketFramingLayer.cpython-37.pyc create mode 100644 src/Proto/Layers/__pycache__/__init__.cpython-37.pyc create mode 100644 src/Proto/Packets/DataPacket.py create mode 100644 src/Proto/Packets/Parser.py create mode 100644 src/Proto/Packets/SynchronizationPacket.py create mode 100644 src/Proto/Packets/UniverseDiscoveryPacket.py create mode 100644 src/Proto/Packets/__init__.py create mode 100644 src/Proto/Packets/__pycache__/DataPacket.cpython-37.pyc create mode 100644 src/Proto/Packets/__pycache__/Parser.cpython-37.pyc create mode 100644 src/Proto/Packets/__pycache__/SynchronizationPacket.cpython-37.pyc create mode 100644 src/Proto/Packets/__pycache__/UniverseDiscoveryPacket.cpython-37.pyc create mode 100644 src/Proto/Packets/__pycache__/__init__.cpython-37.pyc create mode 100644 src/Proto/Vector.py create mode 100644 src/Proto/__init__.py create mode 100644 src/Proto/__pycache__/Vector.cpython-37.pyc create mode 100644 src/Proto/__pycache__/__init__.cpython-37.pyc create mode 100644 src/Proto/__pycache__/util.cpython-37.pyc create mode 100644 src/Proto/util.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6c7c71b --- /dev/null +++ b/.gitignore @@ -0,0 +1,217 @@ + +# Created by https://www.gitignore.io/api/python,pycharm,virtualenv +# Edit at https://www.gitignore.io/?templates=python,pycharm,virtualenv + +### PyCharm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### PyCharm Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/**/sonarlint/ + +# SonarQube Plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator/ + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +### VirtualEnv ### +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +pip-selfcheck.json + +# End of https://www.gitignore.io/api/python,pycharm,virtualenv diff --git a/src/Proto/Layers/DMPLayer.py b/src/Proto/Layers/DMPLayer.py new file mode 100644 index 0000000..34a3d32 --- /dev/null +++ b/src/Proto/Layers/DMPLayer.py @@ -0,0 +1,57 @@ +import struct + +from Proto.Vector import VECTOR + + +class DMPLayer: + ADDRESS_TYPE_AND_DATA_TYPE = 0xA1 + FIRST_PROPERTY_ADDRESS = 0x0000 + ADDRESS_INCREMENT = 0x0001 + + PACK_FORMAT = '! H c B H H H' + HEADER_SIZE = struct.calcsize(PACK_FORMAT) + + def __init__(self, length: int, property_values: bytes): + assert 0 <= length <= 0xFFF + assert 1 <= len(property_values) <= 513 + + self.length = length + self.property_values = property_values + + def __bytes__(self): + buffer = struct.pack( + self.PACK_FORMAT, + + 0x7 << 12 | self.length, + VECTOR.DMP_SET_PROPERTY, + self.ADDRESS_TYPE_AND_DATA_TYPE, + self.FIRST_PROPERTY_ADDRESS, + self.ADDRESS_INCREMENT, + len(self.property_values), + ) + + buffer += self.property_values + + return buffer + + @classmethod + def from_bytes(cls, buffer, offset=0): + (flags_and_length, + vector, + addres_type_and_data_type, + first_property_address, + address_increment, + property_value_count) = struct.unpack_from(cls.PACK_FORMAT, buffer, offset) + + assert flags_and_length >> 12 == 0x7 + assert vector == VECTOR.DMP_SET_PROPERTY + assert addres_type_and_data_type == cls.ADDRESS_TYPE_AND_DATA_TYPE + assert first_property_address == cls.FIRST_PROPERTY_ADDRESS + assert address_increment == cls.ADDRESS_INCREMENT + + property_value_offset = offset + cls.HEADER_SIZE + + length = flags_and_length & 0xFFF + property_values = buffer[property_value_offset:property_value_offset + property_value_count] + + return cls(length, property_values) diff --git a/src/Proto/Layers/DataPacketFramingLayer.py b/src/Proto/Layers/DataPacketFramingLayer.py new file mode 100644 index 0000000..72bab5d --- /dev/null +++ b/src/Proto/Layers/DataPacketFramingLayer.py @@ -0,0 +1,66 @@ +import struct +from enum import IntFlag + +from Proto.Vector import VECTOR +from Proto.util import decode_source_name + + +class DataPacketFramingLayer: + class Options(IntFlag): + FORCE_SYNCHRONIZATION = 1 << 5 + STREAM_TERMINATED = 1 << 6 + PREVIEW_DATA = 1 << 7 + + PACK_FORMAT = '! H 4s 64s B 2s B B 2s' + HEADER_SIZE = struct.calcsize(PACK_FORMAT) + + def __init__(self, length: int, source_name: str, priority: int, synchronization_address: bytes, + sequence_number: int, options: Options, universe: bytes): + assert 0 <= length <= 0x0FFF + assert len(source_name) <= 64 + assert 0 <= priority <= 200 + assert len(synchronization_address) == 2 + assert 0 <= sequence_number <= 0xFF + assert len(universe) == 2 + + self.length = length + self.source_name = source_name + self.priority = priority + self.synchronization_address = synchronization_address + self.sequence_number = sequence_number + self.options = options + self.universe = universe + + def __bytes__(self): + return struct.pack( + self.PACK_FORMAT, + + 0x7 << 12 | self.length, + VECTOR.E131_DATA_PACKET, + self.source_name.encode('utf-8'), + self.priority, + self.synchronization_address, + self.sequence_number, + self.options, + self.universe + ) + + @classmethod + def from_bytes(cls, buffer: bytes, offset: int = 0): + (flags_and_length, + vector, + source_name, + priority, + synchronization_address, + sequence_number, + options, + universe) = struct.unpack_from(cls.PACK_FORMAT, buffer, offset) + + assert flags_and_length >> 12 == 0x7 + assert vector == VECTOR.E131_DATA_PACKET + + length = flags_and_length & 0xFFF + source_name = decode_source_name(source_name) + options = cls.Options(options) + + return cls(length, source_name, priority, synchronization_address, sequence_number, options, universe) diff --git a/src/Proto/Layers/RootLayer.py b/src/Proto/Layers/RootLayer.py new file mode 100644 index 0000000..56f4a4d --- /dev/null +++ b/src/Proto/Layers/RootLayer.py @@ -0,0 +1,51 @@ +import struct + +from Proto.Vector import VECTOR + + +class RootLayer: + PREAMBLE_SIZE = 0x0010 + POSTAMBLE_SIZE = 0x0000 + ACN_PACKET_IDENTIFIER = b'ASC-E1.17\x00\x00\x00' + + PACK_FORMAT = '! H H 12s H 4s 16s' + HEADER_SIZE = struct.calcsize(PACK_FORMAT) + + def __init__(self, length: int, vector: bytes, cid: bytes): + assert 0 <= length <= 0xFFF + assert vector in (VECTOR.ROOT_E131_DATA, VECTOR.ROOT_E131_EXTENDED) + assert len(cid) == 16 + + self.length = length + self.vector = vector + self.cid = cid + + def __bytes__(self): + return struct.pack( + self.PACK_FORMAT, + + self.PREAMBLE_SIZE, + self.POSTAMBLE_SIZE, + self.ACN_PACKET_IDENTIFIER, + 0x7 << 12 | self.length, + self.vector, + self.cid + ) + + @classmethod + def from_bytes(cls, buffer: bytes, offset: int = 0): + (preamble_size, + postamble_size, + acn_packet_identifier, + flags_and_length, + vector, + cid) = struct.unpack_from(cls.PACK_FORMAT, buffer, offset) + + assert preamble_size == cls.PREAMBLE_SIZE + assert postamble_size == cls.POSTAMBLE_SIZE + assert acn_packet_identifier == cls.ACN_PACKET_IDENTIFIER + assert flags_and_length >> 12 == 0x7 + + length = flags_and_length & 0xFFF + + return cls(length, vector, cid) diff --git a/src/Proto/Layers/SynchronizationPacketFramingLayer.py b/src/Proto/Layers/SynchronizationPacketFramingLayer.py new file mode 100644 index 0000000..da126e7 --- /dev/null +++ b/src/Proto/Layers/SynchronizationPacketFramingLayer.py @@ -0,0 +1,41 @@ +import struct + +from Proto.Vector import VECTOR + + +class SynchronizationPacketFramingLayer: + PACK_FORMAT = '! H 4s B 2s 2x' + HEADER_SIZE = struct.calcsize(PACK_FORMAT) + + def __init__(self, length: int, sequence_number: int, synchronization_address: bytes): + assert 0 <= length <= 0xFFF + assert 0 <= sequence_number <= 0xFF + assert len(synchronization_address) == 2 + + self.length = length + self.sequence_number = sequence_number + self.synchronization_address = synchronization_address + + def __bytes__(self): + return struct.pack( + self.PACK_FORMAT, + + 0x7 << 12 | self.length, + VECTOR.E131_EXTENDED_SYNCHRONIZATION, + self.sequence_number, + self.synchronization_address, + ) + + @classmethod + def from_bytes(cls, buffer, offset=0): + (flags_and_length, + vector, + sequence_number, + synchronization_address) = struct.unpack_from(cls.PACK_FORMAT, buffer, offset) + + assert flags_and_length >> 12 == 0x7 + assert vector == VECTOR.E131_EXTENDED_SYNCHRONIZATION + + length = flags_and_length & 0xFFF + + return cls(length, sequence_number, synchronization_address) diff --git a/src/Proto/Layers/UniverseDiscoveryLayer.py b/src/Proto/Layers/UniverseDiscoveryLayer.py new file mode 100644 index 0000000..6bacd48 --- /dev/null +++ b/src/Proto/Layers/UniverseDiscoveryLayer.py @@ -0,0 +1,58 @@ +import struct +from typing import List + +from Proto.Vector import VECTOR + + +class UniverseDiscoveryLayer: + PACK_FORMAT = '! H 4s B B' + HEADER_SIZE = struct.calcsize(PACK_FORMAT) + + def __init__(self, length: int, page: int, last_page: int, universe_list: List[bytes]): + assert 0 <= length <= 0xFFF + assert 0 <= page <= 0xFF + assert 0 <= last_page <= 0xFF + assert len(universe_list) <= 512 + for universe in universe_list: + assert len(universe) == 2 + + self.length = length + self.page = page + self.last_page = last_page + self.universe_list = universe_list + + def __bytes__(self): + buffer = struct.pack( + self.PACK_FORMAT, + + 0x7 << 12 | self.length, + VECTOR.UNIVERSE_DISCOVERY_UNIVERSE_LIST, + self.page, + self.last_page + ) + + buffer += b''.join(self.universe_list) + + return buffer + + @classmethod + def from_bytes(cls, buffer: bytes, offset: int = 0): + (flags_and_length, + vector, + page, + last_page) = struct.unpack_from(cls.PACK_FORMAT, buffer, offset) + + assert flags_and_length >> 12 == 0x7 + assert vector == VECTOR.UNIVERSE_DISCOVERY_UNIVERSE_LIST + + universe_list_offset = offset + cls.HEADER_SIZE + + length = flags_and_length & 0xFFF + universe_list = [] + + assert len(buffer) >= offset + length + + for i in range(universe_list_offset, offset + length, 2): + universe_list.append(buffer[i:i+2]) + + return cls(length, page, last_page, universe_list) diff --git a/src/Proto/Layers/UniverseDiscoveryPacketFramingLayer.py b/src/Proto/Layers/UniverseDiscoveryPacketFramingLayer.py new file mode 100644 index 0000000..baa71e1 --- /dev/null +++ b/src/Proto/Layers/UniverseDiscoveryPacketFramingLayer.py @@ -0,0 +1,39 @@ +import struct + +from Proto.Vector import VECTOR +from Proto.util import decode_source_name + + +class UniverseDiscoveryPacketFramingLayer: + PACK_FORMAT = '! H 4s 64s 4x' + HEADER_SIZE = struct.calcsize(PACK_FORMAT) + + def __init__(self, length: int, source_name: str): + assert 0 <= length <= 0xFFF + assert len(source_name) <= 64 + + self.length = length + self.source_name = source_name + + def __bytes__(self): + return struct.pack( + self.PACK_FORMAT, + + 0x7 << 12 | self.length, + VECTOR.E131_EXTENDED_DISCOVERY, + self.source_name.encode('utf-8') + ) + + @classmethod + def from_bytes(cls, buffer, offset): + (flags_and_length, + vector, + source_name) = struct.unpack_from(cls.PACK_FORMAT, buffer, offset) + + assert flags_and_length >> 12 == 0x7 + assert vector == VECTOR.E131_EXTENDED_DISCOVERY + + length = flags_and_length & 0xFFF + source_name = decode_source_name(source_name) + + return cls(length, source_name) diff --git a/src/Proto/Layers/__init__.py b/src/Proto/Layers/__init__.py new file mode 100644 index 0000000..d33a06c --- /dev/null +++ b/src/Proto/Layers/__init__.py @@ -0,0 +1,8 @@ +from .RootLayer import RootLayer + +from .DataPacketFramingLayer import DataPacketFramingLayer +from .SynchronizationPacketFramingLayer import SynchronizationPacketFramingLayer +from .UniverseDiscoveryPacketFramingLayer import UniverseDiscoveryPacketFramingLayer + +from .DMPLayer import DMPLayer +from .UniverseDiscoveryLayer import UniverseDiscoveryLayer \ No newline at end of file diff --git a/src/Proto/Layers/__pycache__/DMPLayer.cpython-37.pyc b/src/Proto/Layers/__pycache__/DMPLayer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3692abc37f7e711513b90fa80e07a24f899395d GIT binary patch literal 1629 zcmZ8hUuzpj5Z~Q9olYmomJ`PzrnK%u3W5?rDYS&rTDFwhG?s-V3^`hs%k3&YThgh! zr+|(061(sH0DXv|Q2LejwNL&EeQ9U*EZcaO{oTy$pPT*7%lsvDEW~HN4S?nxECyR1nrZ0;TqPGPMsR>sJ%Nl?8T@r zn+w7=4E-8Fl8_1#GC^T43ti!a1>uICEPnK*cSXaJ3}jgp{$Ror#Y;D=2w#*gNm!LD zqACJWzN8m4Too1g?~3tT2i@1vnN-(TaJZrX*9hm;&$srr;;kJ(=yhhik(|8Cj?L;+ zrBkW0GyXmr&7_X;!r1VOV;6?r0}ymhT`-+ewJz8x)teKzenvh};be5qE|#-j2^VI+ zUCz$woNzX0fQ}$YPsciz{I?1&7U1NBGD7OES!rqwt|aNCtyHRv13oGU2vJ3Vx?@}| zN5ebI-$a#R;@__u$LUx$PNSruT76x!c_RiN8AR9W)2|ZSk+B243-g zd%(NB!*07bcw;u3tyZty@AJW%ZksndE#7JlnpQI#ul9TWyS4mgsaad@+3)Q3+6V2< zK$YP1oMNW%ZpM2%8xEzi?B-BGbBXh}XPMNTKLJ&*0}$#`m-&dcSDb*IKe|WX&4$~w z!hzluq)?hZ{aN5MPcDBiVJ@Z_4EVO+9}gtX3hsXcadGtURura4BDR6 zEaRXZSd)PUgY9e8C_pZs!`EyvCff zIa&`CridxeCKw(*ROwjNz@ji|6vjraAv{8OjDXab@?N{yYWH}5KWx`4#)(H-A#uh_ zheIthQyY$=cbZ2N!EdV3doSZGRpGNp2n9rEXH#kCMU+KW3pa*|(iy)k+kB-C*KPzz z>R8FKoMhqp?IK&-JWgj|ee%GXJ9Af652GI7ee=LS2k-N+7e8S&x{`MmKmyd*`QzKL z-|c`$&=z~WhV?dy#*%Xra6V4OY=m-!^IvDtD4%)2U{12--jAbEtdn!8HjzOmnPjG5 zb4yjhpf=E2jz^K!W0@VNLVbp2d>-xr##P~?h8d_aTsN7^TpF-i(XTOT=j(1B@``;u hUL4t|Fc*`@4 zKk?zTnPA+9u2ulJ!AW8Sc&7=O(0~%O&BUBofmPa8Vo#jFA;#ARx4HA&;LZ^ZTu!!) zu6qJ&7=td+?natFNWv#zI* zpzs;ODSUQE*tf0wV?mahxmRRCT_@38a zP~PCp=k^f^mU#=pUDnsu!#vyyqkWM-kl`dwpL`o03i*$y$Z1q>or{W-z~r=whFh?f zJ$wK4Yu(;F$m1+kCmoo6av$MmfI-*M9xFLuOxGEkWPF+ku$zoMorVdr!&q?j!RBzy zXWQQo)*cQw2OB|uw6Qq|E^Uv7e*Y00`NKyWgZ{{051Ly;|M7QR0C>cLOD=&q zyLPklu=Ba<+=IT_`4jXjf)wJPVN}7IH3y zQhHg5r&E!lN~V(?A+?)TG-_{}#?ORQB0{-f!#k>Y4Z8XrfRln)FtktP6;Ahwx}JiL zbK@71lY$-*Zo=3{_za%r!gGaNFuH!u(*jR>pQ_Qq(_VP)atA!qbDr+P^C$EyNMSHq zP(ZUV0jEBD@0V*7Q5s z6G)ZdZpb#mC4|ceZy;PjxC+qqw53Ec{vWPqVv#MFiOP)AIA;vkR@VUxdY!b%qEm;Q zU9%e(sOEHy2=|8#?+xf>qV9o_8!v&ZJql?s_RLiyxAuUfJ*aL@k8#X{UV~nT-hkdb zt^sA{AT|y_cJ?$MfAU4Qr5%;aX_Ra007_Xmw)$(|FsPeH{ZX}dREKW+cR#yZ76(HI ze^j!k9Z(q@N*A+87Sqe@cd2%E zrsFXP-O0vdCGrSk#)f5#3NJ}Zz&IrhbViTOAH2Cax90ZTnY(juUYpkolasIDxCG_i z$xYCsg|x!cO8I1R^S&`}FnkODL9)6f2=AEZHecb z#J{CPrAjQrau?Me%dLA+m_#a`3Eg<;_t*U)+ujI#ZN_P?O;Dn?%hbwuaW1MuH=-m| zY9jL8jLVO4_-q%Ygw@+|?UVi}ummgo2F#}$7_ je^9T6rg@xHS-^!~_eJe}S^afZurd{X+apcdBu(>g_4?vo literal 0 HcmV?d00001 diff --git a/src/Proto/Layers/__pycache__/RootLayer.cpython-37.pyc b/src/Proto/Layers/__pycache__/RootLayer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad7c9b7ec8eb3b22c55be6acdc06058d00ceb50c GIT binary patch literal 1541 zcmZuxOK%%D5GJ{+)#_Aw_|rDo_jR`%t8j<#l5;kqlWdibVrry`YuNEFA(xK8n?rN z$ukiB2`E7XoskgVY)0oSWR(0!gd^N5BHT+BI)WaOR^bL>NxwyncNFwSgJF#J?SMbz zJ08JAl8_1#GC|>67P`U-3&IUOS$ykD@0x}sS(X)95rsF7@I>*-4XeTzr7IHFWL?x@ ztt`rKn5c;ARpF9`8=?joY?#t8O|uu#xl}g|_>ZEXbQM(hu=jb;+3tJ`^NZ$3PoBfm z`9g#KNq^= z0G5pWL6tLU*;~IODdcx(@$*-T@qecGSJ@A0bLXX3UK>2E&`=er5LzPeK;75c+mN>!*{!*ZrEJg!Ox?hzZ>it2kKD>yYf&KaXZ(z zTF%Drx&I;xG5Y80_DMRI?P-*>l{`&#J4#X=#f!F9ar;1}S=zSP>h>MX+o$Ko=R8>? z8RvD_#G*~;Bf3c&%%dK?Xs&~A17qw94t$qDEUcfxBqMJDnh5|i0azw3NCBWG6K{ur zE`s>iMSzO+6LJa_m5iq|brxsFJ&oe2sT_2BKk>c6@MU*oY6ruh`*P<+zz_Gsz|;>0 zhogJ;R=3yZ7$1!I{%+78?eFae!}q{xQB{G&EJC@efoV#dAD?GZbN(Ti8repuOI-#6 zj}LP3@P6g*qFc;($7kcQRK`okV=c27d4&UyBeu$dF@eb)7{IA(=NE6~tlU*$<*kY< zA6YX&K7E$Cz&Q&PSl?NzfPjIuXDv_AAK>VMee}+Do{?2)NtUH$ap_+=mU%Zwfg5Cr zrC+P4fP}b%7 literal 0 HcmV?d00001 diff --git a/src/Proto/Layers/__pycache__/SynchronizationPacketFramingLayer.cpython-37.pyc b/src/Proto/Layers/__pycache__/SynchronizationPacketFramingLayer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ab4b8881c2bc37620dfdfe8f6fe427d10b172ff GIT binary patch literal 1464 zcma)+&u`pB6vyX>?e+dhnieEbMWyWpu?1z-QgK4iP2!RO-9$-Lfdv{lp4r4*ubs|# z5m|XJB!32n=7jibxX+c-{tIv@@7Ymmo)TL11?{(UwIYV37gWD-USI;sx8~nm(2@$PQ#9D z!EPOU|KKc(PjsFov#3b&Y%hw(s(7lSNs=9Z8=WaVTfN`i?mjl%jqW4Uee`pWTQ61F zadBdA8TE3ivRH|1Iyq9>zGvQ!CL$@dGA70k$A)*rvI*UUU?eT61CPd3zbo08n!6c* zDabDrJnYJ|E;)D}FFge<`8k!&n3*kHS<;dSRx+@> zo@-YJ#wd;123qIZa!5zxmuVM`hpQax7?qCx^Z0k7JK+86S^p%TsQx%g`dXdlrXMA_ ziQ=qpbll(5d6D-kcBX$L-u2Tn>kE-&Ng)Jk$>0uz-i2$8dDNq`2R8><28c0ZY@%E=>@0-EZ-o7^TLIZ2fcCW0xmX8$SGv*ThA1F8W+|%1u@w6-eB_^@pO0p z+2F9off((*;NhnaMeyBWFx(2Z#KHH&&F%f&;Z8U>+}RyoBT01|)>qtWvx2WTg*ZAZ zlo8?`m|o@VP>1;xES-J)e{#NxP#trOvcl#=$8)SQ{~89%%t0pXlKx{2;^j0- zYfqhBm9!s6X>5|2vhD3)uodi!gPkz2Jjn{{R%fGE@w4%SZ97gQViuwNHqD$>NQtKJ&)QF=ID(6}qmq?md zOoj!_Dopbk5J@EM5g-4oNBhiY6nU#>^|{X}`Ibm7?JFYfG4pLn4@lFwg>$6Sq&eS- zObUPJsJ(HxyC0%_GHhU0VVXT4iuhC#pGoRlieKBxx}mH^&Ul1oeSEAD&J zmd+LNYpO2ms;Vl|eaU21dRO+C`VCnF9~$}W<2ZVzv{9Rp2@~Khc7h9~FTF=gTT3fu zX?R3^|L7^KDsbp?rAZskVxx^L6v?gXPhiH2Lqzw51&q_0|MLDbS}keF5wB_;^tmeFBr zPbX>8Dw1GYZ%@wh;39X0h~g*}q6QYt3=l#Wi*K5GbcQ(;zsrvvurN6tV(>UHU<{|o z*a|Qyxdz-$q1J#}>m=o;HgFEi%8fmOd`foh!m4^hzaY2$8YruYo#RM=YH+EzF#7EYMkL;0?S(1JY4--oA)6{warHfF)>hod+ zWqIn%kx>QqS*v8^9+Ocutz>izb~1O4oZ03V-1&Stb+bw-lYDGJ!7q-yta@FA8@i>ROO_JU(0f>?^X z?%_OBVVdYS`SfQdPorobqJ+4t4SZHPjsBll4?Qe%`w8qQE8m`H({ze?m|Zr*X6Yik zeDpwe-<*fmTV{9)UsD|Pl@PfnL_d+k9`bb|&WAy-)Rd?cV7Xz?3r%#X^oQuA6~(E> z_mkU2;plgP*9$19h0rQZU!^CB)E}c58^Aq+g{e6ZOp8HWu|PdG-*BfGEi_H1Op%jb r45IkBys2KaiRGgb&>~G}<(}o@qT(&MUzQPlg>T(p<8o=8)vf;kDE6Bp literal 0 HcmV?d00001 diff --git a/src/Proto/Layers/__pycache__/UniverseDiscoveryPacketFramingLayer.cpython-37.pyc b/src/Proto/Layers/__pycache__/UniverseDiscoveryPacketFramingLayer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e46fae15b18a55de9c693d0e1b972bfdf1ce4a10 GIT binary patch literal 1436 zcma)6UvJz*5Z^zx&$&P0C^5JIRV&AGG!E>RMqVu4n!cQ0|zXNTRr zikvPlBp-u^@)dZ28M`5U=tD-@+1c6k?96X};|IN7n}GcF&L2O&?-BAh zF0O=wu@1w03Q7`53zFc>3OZ#8qiFMjPrbyW7NnlpR&Z4beBZIC45Il5p}_S zyt%iv1J*66vPvpps+rD|DATFR@YI$3f9HMhD3VY~5+-TFm3QtdenFE!wNxnC?@V&( zoq5TU^kr~HlD6u|mJH9xDNVX^3GQ#ZkA5ig=Smwj%uQB-b-bNs6J;Ojbefk3-=)V& z&wC%NJX%>ZE1$zy`!!-NC{%f14_)WwBr!1*oN;WzFkga_bU{6EO{jiTvI#Y}OMu3b z->9Vvc1k4&-yK{p=z<8gV4%4qkf1lx6e8sRzDCI9I#`kCmN$%1+U8XmYh7u_AsOw% zo(}K;cb-wj_}cR)(H+?MXKQd+P1RtM<^!#cDl&jMxx?D530Vbe?YAF%m*tt zZ%KARFFZhqk8*NE$lRaV@!c*^n z1U#u0Jl)10&K>iWeObJXe{mbd6(!Htsc0%v9OKO6vE}eO*m$VfGsSiuL=|R6r86S-%x7 u)&3}GVD8opwz}V-Q**H0xMnslYLM&mue!j6Uo}PD#|AOjb~!eadZ literal 0 HcmV?d00001 diff --git a/src/Proto/Layers/__pycache__/__init__.cpython-37.pyc b/src/Proto/Layers/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1c4c074f58b83199463fdcdb8810374094855db GIT binary patch literal 406 zcmZvZy-EZz5P*~H&#iLT9=2k&jcF`JL>8-477v@iv4q{=h0D*8L}7g)@pUY(wel6L zoCLP=67um4GntU&Zm~E;Fuu+{HXDr4cMPUMKyG3A6<|OER!Ad;aCD-u#tbLV6w!o{ z=AoVXF8^&wna8?x@$xQ<$Rmn~GGYe! zM6QY+@q0zLRtvi0k~*=so^okD?+x{?r>(QW($v+{u9HTFuDjfihw56};Z=#7_!2&T K!ko-8OyD0neQNpu literal 0 HcmV?d00001 diff --git a/src/Proto/Packets/DataPacket.py b/src/Proto/Packets/DataPacket.py new file mode 100644 index 0000000..e63eb28 --- /dev/null +++ b/src/Proto/Packets/DataPacket.py @@ -0,0 +1,49 @@ +from Proto.Layers import RootLayer, DataPacketFramingLayer, DMPLayer +from Proto.Vector import VECTOR + + +class DataPacket: + def __init__(self, cid: bytes, source_name: str, priority: int, synchronization_address: bytes, + sequence_number: int, options: DataPacketFramingLayer.Options, universe: bytes, + property_values: bytes): + assert len(cid) == 16 + assert len(source_name) <= 64 + assert 0 <= priority <= 100 + assert len(synchronization_address) == 2 + assert 0 <= sequence_number <= 0xFF + assert len(universe) == 2 + assert 1 <= len(property_values) <= 513 + + self.cid = cid + self.source_name = source_name + self.priority = priority + self.synchronization_address = synchronization_address + self.sequence_number = sequence_number + self.options = options + self.universe = universe + self.property_values = property_values + + def __bytes__(self): + dmp_layer = DMPLayer( + DMPLayer.HEADER_SIZE + len(self.property_values), + self.property_values + ) + + data_packet_framing_layer = DataPacketFramingLayer( + DataPacketFramingLayer.HEADER_SIZE + dmp_layer.length, + self.source_name, self.priority, + self.synchronization_address, self.sequence_number, + self.options, self.universe + ) + + root_layer = RootLayer( + RootLayer.HEADER_SIZE + data_packet_framing_layer.length, + VECTOR.ROOT_E131_DATA, self.cid + ) + + return bytes(root_layer) + bytes(data_packet_framing_layer) + bytes(dmp_layer) + + def __repr__(self): + return f'{self.__class__.__name__}({self.cid!r}, {self.source_name!r}, {self.priority!r}, ' \ + f'{self.synchronization_address!r}, {self.sequence_number!r}, {self.options!r}, {self.universe!r}, ' \ + f'{self.property_values!r})' diff --git a/src/Proto/Packets/Parser.py b/src/Proto/Packets/Parser.py new file mode 100644 index 0000000..fc19daa --- /dev/null +++ b/src/Proto/Packets/Parser.py @@ -0,0 +1,66 @@ +import struct + +from Proto.Layers import * +from Proto.Packets import * +from Proto.Vector import VECTOR + + +def parse_packet(buffer: bytes): + root_layer = RootLayer.from_bytes(buffer) + + if root_layer.vector == VECTOR.ROOT_E131_DATA: + # Definitely a Data Packet + data_packet_framing_layer = DataPacketFramingLayer.from_bytes( + buffer, RootLayer.HEADER_SIZE + ) + + dmp_layer = DMPLayer.from_bytes( + buffer, RootLayer.HEADER_SIZE + DataPacketFramingLayer.HEADER_SIZE + ) + + return DataPacket( + root_layer.cid, + data_packet_framing_layer.source_name, + data_packet_framing_layer.priority, + data_packet_framing_layer.synchronization_address, + data_packet_framing_layer.sequence_number, + data_packet_framing_layer.options, + data_packet_framing_layer.universe, + dmp_layer.property_values + ) + + else: + # Either Synchronization or Universe Discovery, check vector of next frame + (vector,) = struct.unpack_from('! 2x 4s', buffer, RootLayer.HEADER_SIZE) + + assert vector in (VECTOR.E131_EXTENDED_SYNCHRONIZATION, VECTOR.E131_EXTENDED_DISCOVERY) + + if vector == VECTOR.E131_EXTENDED_SYNCHRONIZATION: + + synchronization_packet_framing_layer = SynchronizationPacketFramingLayer.from_bytes( + buffer, RootLayer.HEADER_SIZE + ) + + return SynchronizationPacket( + root_layer.cid, + synchronization_packet_framing_layer.sequence_number, + synchronization_packet_framing_layer.synchronization_address + ) + + else: # VECTOR.E131_EXTENDED_DISCOVERY + + universe_discovery_packet_framing_layer = UniverseDiscoveryPacketFramingLayer.from_bytes( + buffer, RootLayer.HEADER_SIZE + ) + + universe_discovery_layer = UniverseDiscoveryLayer.from_bytes( + buffer, RootLayer.HEADER_SIZE + UniverseDiscoveryPacketFramingLayer.HEADER_SIZE + ) + + return UniverseDiscoveryPacket( + root_layer.cid, + universe_discovery_packet_framing_layer.source_name, + universe_discovery_layer.page, + universe_discovery_layer.last_page, + universe_discovery_layer.universe_list + ) diff --git a/src/Proto/Packets/SynchronizationPacket.py b/src/Proto/Packets/SynchronizationPacket.py new file mode 100644 index 0000000..b6303f9 --- /dev/null +++ b/src/Proto/Packets/SynchronizationPacket.py @@ -0,0 +1,31 @@ +from Proto.Layers import RootLayer, SynchronizationPacketFramingLayer +from Proto.Vector import VECTOR + + +class SynchronizationPacket: + def __init__(self, cid: bytes, sequence_number: int, synchronization_address: bytes): + assert len(cid) == 16 + assert 0 <= sequence_number <= 0xFF + assert len(synchronization_address) == 2 + + self.cid = cid + self.sequence_number = sequence_number + self.synchronization_address = synchronization_address + + def __bytes__(self): + framing_layer = SynchronizationPacketFramingLayer( + SynchronizationPacketFramingLayer.HEADER_SIZE, + self.sequence_number, + self.synchronization_address + ) + + root_layer = RootLayer( + RootLayer.HEADER_SIZE + framing_layer.length, + VECTOR.ROOT_E131_EXTENDED, + self.cid + ) + + return bytes(root_layer) + bytes(framing_layer) + + def __repr__(self): + return f'{self.__class__.__name__}({self.cid}, {self.sequence_number}, {self.synchronization_address})' diff --git a/src/Proto/Packets/UniverseDiscoveryPacket.py b/src/Proto/Packets/UniverseDiscoveryPacket.py new file mode 100644 index 0000000..790688c --- /dev/null +++ b/src/Proto/Packets/UniverseDiscoveryPacket.py @@ -0,0 +1,46 @@ +from typing import List + +from Proto.Layers import RootLayer, UniverseDiscoveryPacketFramingLayer, UniverseDiscoveryLayer +from Proto.Vector import VECTOR + + +class UniverseDiscoveryPacket: + def __init__(self, cid: bytes, source_name: str, page: int, last_page: int, universe_list: List[bytes]): + assert len(cid) == 16 + assert len(source_name) <= 64 + assert 0 <= page <= 0xFF + assert 0 <= last_page <= 0xFF + assert len(universe_list) <= 512 + for universe in universe_list: + assert len(universe) == 2 + + self.cid = cid + self.source_name = source_name + self.page = page + self.last_page = last_page + self.universe_list = universe_list + + def __bytes__(self): + universe_discovery_layer = UniverseDiscoveryLayer( + UniverseDiscoveryLayer.HEADER_SIZE + 2 * len(self.universe_list), + self.page, + self.last_page, + self.universe_list + ) + + universe_discovery_packet_framing_layer = UniverseDiscoveryPacketFramingLayer( + UniverseDiscoveryPacketFramingLayer.HEADER_SIZE + universe_discovery_layer.length, + self.source_name + ) + + root_layer = RootLayer( + RootLayer.HEADER_SIZE + universe_discovery_packet_framing_layer.length, + VECTOR.ROOT_E131_EXTENDED, + self.cid + ) + + return bytes(root_layer) + bytes(universe_discovery_packet_framing_layer) + bytes(universe_discovery_layer) + + def __repr__(self): + return f'{self.__class__.__name__}({self.cid!r}, {self.source_name!r}, {self.page!r}, {self.last_page!r}, ' \ + f'{self.universe_list!r})' diff --git a/src/Proto/Packets/__init__.py b/src/Proto/Packets/__init__.py new file mode 100644 index 0000000..0d1406b --- /dev/null +++ b/src/Proto/Packets/__init__.py @@ -0,0 +1,5 @@ +from .DataPacket import DataPacket +from .SynchronizationPacket import SynchronizationPacket +from .UniverseDiscoveryPacket import UniverseDiscoveryPacket + +from .Parser import parse_packet diff --git a/src/Proto/Packets/__pycache__/DataPacket.cpython-37.pyc b/src/Proto/Packets/__pycache__/DataPacket.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd075b9c6589eab2fef62e359428cfc1d14ee70f GIT binary patch literal 1734 zcma)6OK%)S5bnpkcD-IN#$Xab6gV*w@+yFY6d`02FE7E`a;zLiBCW}EC!T%GY`S|R ztu?-|KIX(Va7G;X8~lj5a`IpB1*&?-#Nc%-Ixlr@7xlJT6xoR`i~KaTd0B{5O0A5kH;j5ZR|R^^r;p%OVL3wsQ%Cb6 zf2Ooi^~Ow>Go|f9JWD5YWiosLHk26Id(h3F0G3pANhKXK)3fv^3S$OiHm2q_jwP?S z2QFi(Kb0QL-YpmcK6rlDSo)3SLm7ajyk;3TmeyH@a7whKjrDUGf%VT<))lRY zU=;&|vjM%z1N18&FsK5+unGaADgtatf{`6w^x!oYy8xP^CJ`9I-v~IDQy9nXnom?w zclV5e2tnWmT9;Zw{t+D^V2m^-rd~tnAgm*F0f0l#sLA8kwf~*ycfjrPv;IjrRsC_A z_qCdprl01eNwcDFbk;xAr7iob#5DbvDY7$L)R7Q*ky{}G*v8xfAiPI=^k&m}KZGE?+Q+@RM+XPTVsPh^J7RzDc+as@`;Qh@nb_0YXws6? znV4W5NNz}|17hY1fq1;C1kF-gL$z4xj<^-vz&o{sa2pD76NUz9C6v)FjX0xi8o}3b zT8E!*{fC6c?OzsOjr1DnH!^5s*vP1nEs*@zO^C5K zyrdtVvX5?G(irj`E}l(NV}!tL!a5_w>*jAvUG!d!1?&T9tcBQt+Z*J8&{r~VwLXm3 z^!u<{w}qINaz25x>y8jl=jo)m$-B7Bjny^J3%lY!JXqBA$)*}e08YHI6KHA1`eu9E_ukX^QMp`DV34)1uN!$q`5_O}p~2=MfZc;B zPy#eidU902q+r>_6sJid`4sC3pzk!)K|II*Y{NVh8yyhD}D2edZ6;$^u&$6 zSyA9l;}+=W$7;U-C<01=GGGocKi2vShgL`7XFe|mQ%~9}bfAxQh;bHhZb#iS*%4p* zh_X9~`<*XOBS8#PAHX~5p(TUtLr+q?%Z!$1@nNvMzA$Qxo| z#WW-|DDlHoQm&5>9tFkvN8xQ{8rVm_uM z#*~lTeQ%J+3>c@0&qXnbVxa2Ek3Fk%EY1)qMc3w6&p0r!dMz7v&w3?!FQfxOm z8?7y;{Zh=;83X4K)1j15aiw#T>WpG6%~TOrpHCRuA@d1vAI-2`KBbgZvU2J^GZuR6 z?P8H1c#OO0wmdD2I|v!CT2z;fEKq2+J4m~|8bA|4S#}YMleTdp$_K+Z+tM7E^{)Nj zn3-1Ve?tb-)MmS1nW30+`lirzi1+(W?JXJN+MXBID2@rMc_Cq*AJrK3YnzmCQp@sY zutM|c&3GhAvD{7~$~Vqzm=sh{ORA0vnvNDU73n8F%UD#;sfARY$t>fvF0F!}YK|_! zB1&oen`u9oC}*b$o2hW?*xNDE_msLwlRGwDm;S8#LlPtd{6PMmnB;A#7P3%D`vYMC BlmY+% literal 0 HcmV?d00001 diff --git a/src/Proto/Packets/__pycache__/SynchronizationPacket.cpython-37.pyc b/src/Proto/Packets/__pycache__/SynchronizationPacket.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96c6f1c851bee6e0eb06657a18007e26248ad8f5 GIT binary patch literal 1102 zcmZ{j&uiN-6vrh?c9X1KvqA~+(o%+D2-i|uC$Zg1${{7Y zEd4VEJB}Uq@94Ty|Ak$)_nek>qm$9s($jl-@<-2G3kxj*?fc5t4__D|KX7u>U`{rm zn^h1=Bps51CbaMpkK)`LvVtd^lGj8s$uEiIQ!nwQzfZ#83Svm;xn{4b?7MWVw0pci zF0)fzmH9<#^QzoSvw^a&bXw%)N$nC+7aYdh2fMut!*3dg!3K2m6hx7PN|JbrDXy5L zpPBR|yX26VOaGE2fehdPb8h+0bRlyr%cWa1>U^ZiOo?(-9Kq>2=I_&qR7$Ok$uK)M zd?S)==w=VZk_nwsNe7;3Tl$GgZ{l%q8BqO1vH>;EN&tl`;K{&~gXcQVCv-vtc!RPD z1Lcyynf>ln8}`){@4OQvxZyKXCf{V4Tv<}d94yA!!+;O9Z$N!kW5xoej zKewXOs!-7&%_FVODifu7WzwvSjLxDxUD+y{U5AP8#I|}ib`2r&GPgotW-|{$Xq&Fk zwinQVUOc=z@Fpn3ufm25k!8(s9R?PjJ`m{xk3O5SkJNI@!9x3fhuEM$2lfWoJ=>gk zQwj>)J4lRn!$t_?5W1AZmGAsdm!Sq=W8NkA^N+?>nULxG;Fc^L&+1YP>)LH;DC60<209bGE!PyHjuZk(ni-dj@FkPkNO z20yw%mzo-9-7s+T^>we-Kb)xn%?MuG4^?KNx-hH`xwUbfr~c-~i`nsB;-%Ip+H{`% E1_+D_bpQYW literal 0 HcmV?d00001 diff --git a/src/Proto/Packets/__pycache__/UniverseDiscoveryPacket.cpython-37.pyc b/src/Proto/Packets/__pycache__/UniverseDiscoveryPacket.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9fc9e771924880360cb439f964c09f90f252376e GIT binary patch literal 1696 zcmaJ>-ESL35Z~SV@Y%6TC}~pyNGW|Nma1A6hzEqKmfCzsl~bjmpp&ZAad%D5U+3;_ z5RRM|oPU7l!W$Ceg+FLtdCI?#7x>MdjUtNK)y~cC%+1WsZ)QJhwHgfLkMVEMe+n7< zlQyg2fq8(X?}KD4<0CfaG3UgKkr;ciH}+$H9K?Y;^G4yg7S}lYf@OXdoUtreh&al^ zr>tE&hYi-|)_+`R)AnqAzbwt;WR@#?>+4DJeXexgEp%Ffn>|U=VQxNG$+(ytR!Y}j zQ*!697(VMgI@sG!$-!#iDplwogUMOUGZu^7%l$mS40G>oT<7N?6Pb7B$F(Y43N@>p zvACW^2)S;zU-MZ7)()(f7Mb19<*`b0IZ4L3^{2^UZtJ5&8|m2A@$y=7ge#{M5{()b zW%d!4{uRWqIbZOM4~5<|{6~(xz+Mcw-lcu!%{?E#47vI!^KtsgL~yp0_)AIONe)&L z*a%=FfObZjKfF5+y6pMZX$VOONeFKPlDr&z1OIa-#aw{G7pOn?L4$b!8fJ{}>z{8T z*7FA-iWB!2NWla+EGSrSluzuHhg#>#6y>C+RH;-%`gI~yXKI5;69oFc&POlSD%fb1 zzTcU;hCeR4ouhJ`cZNyPQTepgounvrl1@5WrJX0LG-aoPM|alXc6U0nk(9-xFj7)v z`UVK&o0vP8o4modM98aovb)aA%0xHs;# ziGRvXXu<)X^FhtYqJ=mWrf%vu6Le-8gAM357v8C7T60(dMP)$JqKerjTtr_HF6}Fd z{M(H$dk?$4efjjOxToI4iA(mS+*71B1X73QsKSM6QBiT)tNVL<2eNnX!+Wy#?Ln{K z?R6bIHu!F4a^3dTTTqK{tbmc(s$b=Z8aclGACjqSW%;7&){9kvy@PC?YA zbl#-g##ZluFfRC2?qf!t07Mm~-O0`M5G}3zgArjxmFF;`X92kdMz8P?fD^Ao=CE3R z{pB}UenWh{Uz*6c-@o7=oQONS7rc!sM!YF{UQ0=(MK6JrYm2(gT?+qwXZ(nYR#M(U zSen|2@&Bv7O1a-|sGCr=4JpTEc07V-+m!OQ#{JfmTkJWyX#(Jtz0EhfmOA*6h6ySgNJ}j aIU|>xIo}TT=+o*3_X#EEwkfuF)B78-_m;l^ literal 0 HcmV?d00001 diff --git a/src/Proto/Packets/__pycache__/__init__.cpython-37.pyc b/src/Proto/Packets/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6169bdd0a2c1d1466592e0d97ffd00a241644b9 GIT binary patch literal 306 zcmX|+y-EZz6or$_53=l*VsAH%X|!7wk*#H5u?a{BnZSn4&u|lk@rA@^@HuR@wel6L zycyZOAt&F-AvejxYPBF(U)S%?pSXS(b1H^#k2Bq(3}m2=cp?Zb%pCPp(3va8JQHl@ z+Eu<5HFC2fUHe1vXh)BWt;(ub`d~7;%iR?89%8U>D%%*&!PQf+uLhFY+N2}WbdHvz z!hJc;Js!IT%IlyiQlp5rFF8Pi=7T_6f+D|nd>_5x2W2^!F($5TOiBlyK=U4Aj{N_U d#HF;sW+`vR>3FgBad>fNQ+|+2rzOR~{s8>SP9p#S literal 0 HcmV?d00001 diff --git a/src/Proto/Vector.py b/src/Proto/Vector.py new file mode 100644 index 0000000..005eeed --- /dev/null +++ b/src/Proto/Vector.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class VECTOR(bytes, Enum): + ROOT_E131_DATA = bytes([0x00, 0x00, 0x00, 0x04]) + ROOT_E131_EXTENDED = bytes([0x00, 0x00, 0x00, 0x08]) + + DMP_SET_PROPERTY = bytes([0x02]) + + E131_DATA_PACKET = bytes([0x00, 0x00, 0x00, 0x02]) + + E131_EXTENDED_SYNCHRONIZATION = bytes([0x00, 0x00, 0x00, 0x01]) + E131_EXTENDED_DISCOVERY = bytes([0x00, 0x00, 0x00, 0x02]) + + UNIVERSE_DISCOVERY_UNIVERSE_LIST = bytes([0x00, 0x00, 0x00, 0x01]) diff --git a/src/Proto/__init__.py b/src/Proto/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/Proto/__pycache__/Vector.cpython-37.pyc b/src/Proto/__pycache__/Vector.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d58eb617c0b195514bce5d3352c765e70f317244 GIT binary patch literal 633 zcmY*W&5qMB7_<|o4gDkH!f7SMtwJKIxFSSoEH+{{i4s#$OUMefRaV!Zfcj`Vch7H2&UAfTYROV4Xl_CIz98gQx9Jb3^q64JJ zaJ%J>;%Et#(=iTeovz_d%U#2d{u9HGevfz5=XIOT3{OdtNp(f7}#~}`>7ha|; z$AqO>lH!casb>N#4W^$kp=Ygfim-ehPtUU?j%YxlB&N^*x5Fr(CNrGP>5I>Cq?#Nv zqcJ00L^=5bh5J|j_o@{Bb#diOv8igmxT@-6vG!}Z@KafBD}N>y+e*IP?4_+@ zdO)?#yU>H4)w4WH@2wY)QG8WT+v6PH=^58LFt8s0sAiE! literal 0 HcmV?d00001 diff --git a/src/Proto/__pycache__/__init__.cpython-37.pyc b/src/Proto/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a92bd9acf6fe205cd74ffe7a13380cd1b4ca31b GIT binary patch literal 132 zcmZ?b<>g`k0?EJ2VnOs{5CH>>K!yVl7qb9~6oz01O-8?!3`HPe1o2B(KO;XkRX;m1 zQ@<#+Air2YF*Cn7F*#4axF}gapeVm2Uq3!RGcU6wK3=b&@)n0pZhlH>PO2Tqn9o4W F001rR9vT1u literal 0 HcmV?d00001 diff --git a/src/Proto/__pycache__/util.cpython-37.pyc b/src/Proto/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d4df4d23063207b68c127ce7ae1409af2cd7108 GIT binary patch literal 303 zcmYjKu}T9$5S_gwX9%PTHh#hux~+vsNcteyDH1NbbL8+Yd+h8M5lcVAB54Faz@ORH z$~v7OIC~=G!Fz88-kX_?$0J~T{JcHfvwx=LA3YwXOq#GD7X((}E)j$y0C6q*In>*ntsy?w!GodwY?Zi$hoV;s87if-lc6Wflk2)|HRBL2V66 z;Zo=wT+a3_)!H_w9*asjY%QsxvQ+4eBB#}jv)-!UtNNnd#>wA-CE4IKE;mJk=@Mlu gAl#63k>0Jg9;sWq7e{i!kvP0+tO+$