albibong 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- albibong/__init__.py +82 -0
- albibong/classes/__init__.py +0 -0
- albibong/classes/character.py +83 -0
- albibong/classes/coords.py +9 -0
- albibong/classes/dungeon.py +59 -0
- albibong/classes/item.py +41 -0
- albibong/classes/location.py +48 -0
- albibong/classes/logger.py +122 -0
- albibong/classes/packet_handler.py +61 -0
- albibong/classes/world_data.py +327 -0
- albibong/gui_dist/No Equipment.png +0 -0
- albibong/gui_dist/assets/index-BFSx0nua.css +1 -0
- albibong/gui_dist/assets/index-DAndaN_4.js +161 -0
- albibong/gui_dist/fame.png +0 -0
- albibong/gui_dist/index.html +14 -0
- albibong/gui_dist/re_spec.png +0 -0
- albibong/gui_dist/silver.png +0 -0
- albibong/gui_dist/vite.svg +1 -0
- albibong/photon_packet_parser/__init__.py +4 -0
- albibong/photon_packet_parser/command_type.py +7 -0
- albibong/photon_packet_parser/crc_calculator.py +16 -0
- albibong/photon_packet_parser/event_data.py +4 -0
- albibong/photon_packet_parser/message_type.py +6 -0
- albibong/photon_packet_parser/number_serializer.py +22 -0
- albibong/photon_packet_parser/operation_request.py +4 -0
- albibong/photon_packet_parser/operation_response.py +6 -0
- albibong/photon_packet_parser/photon_packet_parser.py +168 -0
- albibong/photon_packet_parser/protocol16_deserializer.py +302 -0
- albibong/photon_packet_parser/protocol16_type.py +23 -0
- albibong/photon_packet_parser/segmented_packet.py +5 -0
- albibong/resources/EventCode.py +579 -0
- albibong/resources/OperationCode.py +499 -0
- albibong/resources/event_code.json +577 -0
- albibong/resources/items.json +54035 -0
- albibong/resources/maps.json +3565 -0
- albibong/resources/operation_code.json +497 -0
- albibong/threads/__init__.py +0 -0
- albibong/threads/http_server.py +60 -0
- albibong/threads/packet_handler_thread.py +32 -0
- albibong/threads/sniffer_thread.py +27 -0
- albibong/threads/websocket_server.py +168 -0
- albibong-1.0.0.dist-info/METADATA +15 -0
- albibong-1.0.0.dist-info/RECORD +46 -0
- albibong-1.0.0.dist-info/WHEEL +4 -0
- albibong-1.0.0.dist-info/entry_points.txt +2 -0
- albibong-1.0.0.dist-info/licenses/LICENSE +19 -0
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Vite + React + TS</title>
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DAndaN_4.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BFSx0nua.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
from albibong.photon_packet_parser.photon_packet_parser import PhotonPacketParser
|
|
2
|
+
from albibong.photon_packet_parser.event_data import EventData
|
|
3
|
+
from albibong.photon_packet_parser.operation_request import OperationRequest
|
|
4
|
+
from albibong.photon_packet_parser.operation_response import OperationResponse
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class CrcCalculator:
|
|
2
|
+
@staticmethod
|
|
3
|
+
def calculate(_bytes, length):
|
|
4
|
+
result = 4294967295
|
|
5
|
+
key = 3988292384
|
|
6
|
+
|
|
7
|
+
for i in range(length):
|
|
8
|
+
result ^= _bytes[i]
|
|
9
|
+
|
|
10
|
+
for _ in range(8):
|
|
11
|
+
if (result & 1) > 0:
|
|
12
|
+
result = result >> 1 ^ key
|
|
13
|
+
else:
|
|
14
|
+
result >>= 1
|
|
15
|
+
|
|
16
|
+
return result
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import struct
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class NumberSerializer:
|
|
6
|
+
@staticmethod
|
|
7
|
+
def deserialize_int(source: io.BytesIO):
|
|
8
|
+
buffer = source.read(4)
|
|
9
|
+
return struct.unpack(">i", buffer)[0]
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def deserialize_short(source: io.BytesIO):
|
|
13
|
+
buffer = source.read(2)
|
|
14
|
+
return struct.unpack(">h", buffer)[0]
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def serialize_int(value, target: io.BytesIO):
|
|
18
|
+
target.write(value >> 24)
|
|
19
|
+
target.write(value >> 16)
|
|
20
|
+
target.write(value >> 8)
|
|
21
|
+
target.write(value)
|
|
22
|
+
return target
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import io
|
|
2
|
+
from albibong.photon_packet_parser.message_type import MessageType
|
|
3
|
+
from albibong.photon_packet_parser.command_type import CommandType
|
|
4
|
+
from albibong.photon_packet_parser.segmented_packet import SegmentedPacket
|
|
5
|
+
from albibong.photon_packet_parser.protocol16_deserializer import Protocol16Deserializer
|
|
6
|
+
from albibong.photon_packet_parser.crc_calculator import CrcCalculator
|
|
7
|
+
from albibong.photon_packet_parser.number_serializer import NumberSerializer
|
|
8
|
+
|
|
9
|
+
COMMAND_HEADER_LENGTH = 12
|
|
10
|
+
PHOTON_HEADER_LENGTH = 12
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PhotonPacketParser:
|
|
14
|
+
def __init__(self, on_event, on_request, on_response):
|
|
15
|
+
self._pending_segments = {}
|
|
16
|
+
self.on_event = on_event
|
|
17
|
+
self.on_request = on_request
|
|
18
|
+
self.on_response = on_response
|
|
19
|
+
|
|
20
|
+
# MITIGATOR Challenge Response Packet
|
|
21
|
+
def is_mcr_packet(self, payload):
|
|
22
|
+
signatures = {
|
|
23
|
+
b"\x4d\x43\x52\x48\x33\x31\x31\x30",
|
|
24
|
+
b"\xe9\x71\x2d\xd5\x00\x01\x00\x00",
|
|
25
|
+
b"\xe9\x71\x2d\xd5\x01\x01\x00\x00",
|
|
26
|
+
b"\xe9\x71\x2d\xd5\x11\x01\x00\x00",
|
|
27
|
+
}
|
|
28
|
+
return payload[:8] in signatures
|
|
29
|
+
|
|
30
|
+
def handle_payload(self, payload):
|
|
31
|
+
if self.is_mcr_packet(payload):
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
payload = io.BytesIO(payload)
|
|
35
|
+
if payload.getbuffer().nbytes < PHOTON_HEADER_LENGTH:
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
peer_id = NumberSerializer.deserialize_short(payload)
|
|
39
|
+
flags = payload.read(1)[0]
|
|
40
|
+
command_count = payload.read(1)[0]
|
|
41
|
+
timestamp = NumberSerializer.deserialize_int(payload)
|
|
42
|
+
challenge = NumberSerializer.deserialize_int(payload)
|
|
43
|
+
|
|
44
|
+
is_encrypted = flags == 1
|
|
45
|
+
is_crc_enabled = flags == 0xCC
|
|
46
|
+
|
|
47
|
+
if is_encrypted:
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
if is_crc_enabled:
|
|
51
|
+
offset = payload.tell()
|
|
52
|
+
payload.seek(0)
|
|
53
|
+
crc = NumberSerializer.deserialize_int(payload)
|
|
54
|
+
|
|
55
|
+
payload.seek(offset)
|
|
56
|
+
payload = NumberSerializer.serialize_int(0, payload)
|
|
57
|
+
|
|
58
|
+
if crc != CrcCalculator.calculate(payload, payload.getbuffer().nbytes):
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
for _ in range(command_count):
|
|
62
|
+
self.handle_command(payload)
|
|
63
|
+
|
|
64
|
+
def handle_command(self, source: io.BytesIO):
|
|
65
|
+
command_type = source.read(1)[0]
|
|
66
|
+
channel_id = source.read(1)[0]
|
|
67
|
+
command_flags = source.read(1)[0]
|
|
68
|
+
# Skip 1 byte
|
|
69
|
+
source.read(1)
|
|
70
|
+
command_length = NumberSerializer.deserialize_int(source)
|
|
71
|
+
sequence_number = NumberSerializer.deserialize_int(source)
|
|
72
|
+
command_length -= COMMAND_HEADER_LENGTH
|
|
73
|
+
|
|
74
|
+
if command_type == CommandType.Disconnect.value:
|
|
75
|
+
return
|
|
76
|
+
elif command_type == CommandType.SendUnreliable.value:
|
|
77
|
+
source.read(4)
|
|
78
|
+
command_length -= 4
|
|
79
|
+
self.handle_send_reliable(source, command_length)
|
|
80
|
+
elif command_type == CommandType.SendReliable.value:
|
|
81
|
+
self.handle_send_reliable(source, command_length)
|
|
82
|
+
elif command_type == CommandType.SendFragment.value:
|
|
83
|
+
self.handle_send_fragment(source, command_length)
|
|
84
|
+
else:
|
|
85
|
+
source.read(command_length)
|
|
86
|
+
|
|
87
|
+
def handle_send_reliable(self, source: io.BytesIO, command_length: int):
|
|
88
|
+
# Skip 1 byte
|
|
89
|
+
source.read(1)
|
|
90
|
+
command_length -= 1
|
|
91
|
+
message_type = source.read(1)[0]
|
|
92
|
+
command_length -= 1
|
|
93
|
+
|
|
94
|
+
operation_length = command_length
|
|
95
|
+
payload = io.BytesIO(source.read(operation_length))
|
|
96
|
+
|
|
97
|
+
if message_type == MessageType.OperationRequest.value:
|
|
98
|
+
request_data = Protocol16Deserializer.deserialize_operation_request(payload)
|
|
99
|
+
self.on_request(request_data)
|
|
100
|
+
elif message_type == MessageType.OperationResponse.value:
|
|
101
|
+
response_data = Protocol16Deserializer.deserialize_operation_response(
|
|
102
|
+
payload
|
|
103
|
+
)
|
|
104
|
+
self.on_response(response_data)
|
|
105
|
+
elif message_type == MessageType.Event.value:
|
|
106
|
+
event_data = Protocol16Deserializer.deserialize_event_data(payload)
|
|
107
|
+
self.on_event(event_data)
|
|
108
|
+
# else:
|
|
109
|
+
# print("Unknown message type: ", message_type)
|
|
110
|
+
|
|
111
|
+
def handle_send_fragment(self, source: io.BytesIO, command_length: int):
|
|
112
|
+
start_sequence_number = NumberSerializer.deserialize_int(source)
|
|
113
|
+
command_length -= 4
|
|
114
|
+
fragment_count = NumberSerializer.deserialize_int(source)
|
|
115
|
+
command_length -= 4
|
|
116
|
+
fragment_number = NumberSerializer.deserialize_int(source)
|
|
117
|
+
command_length -= 4
|
|
118
|
+
total_length = NumberSerializer.deserialize_int(source)
|
|
119
|
+
command_length -= 4
|
|
120
|
+
fragment_offset = NumberSerializer.deserialize_int(source)
|
|
121
|
+
command_length -= 4
|
|
122
|
+
|
|
123
|
+
fragment_length = command_length
|
|
124
|
+
|
|
125
|
+
self.handle_segmented_payload(
|
|
126
|
+
start_sequence_number,
|
|
127
|
+
total_length,
|
|
128
|
+
fragment_length,
|
|
129
|
+
fragment_offset,
|
|
130
|
+
source,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def handle_finished_segmented_packet(self, total_payload: bytearray):
|
|
134
|
+
command_length = len(total_payload)
|
|
135
|
+
self.handle_send_reliable(io.BytesIO(total_payload), command_length)
|
|
136
|
+
|
|
137
|
+
def handle_segmented_payload(
|
|
138
|
+
self,
|
|
139
|
+
start_sequence_number,
|
|
140
|
+
total_length,
|
|
141
|
+
fragment_length,
|
|
142
|
+
fragment_offset,
|
|
143
|
+
source,
|
|
144
|
+
):
|
|
145
|
+
segmented_packet = self.get_segmented_packet(
|
|
146
|
+
start_sequence_number, total_length
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
for i in range(fragment_length):
|
|
150
|
+
segmented_packet.total_payload[fragment_offset + i] = source.read(1)[0]
|
|
151
|
+
|
|
152
|
+
segmented_packet.bytes_written += fragment_length
|
|
153
|
+
|
|
154
|
+
if segmented_packet.bytes_written >= segmented_packet.total_length:
|
|
155
|
+
self._pending_segments.pop(start_sequence_number)
|
|
156
|
+
self.handle_finished_segmented_packet(segmented_packet.total_payload)
|
|
157
|
+
|
|
158
|
+
def get_segmented_packet(self, start_sequence_number, total_length):
|
|
159
|
+
if start_sequence_number in self._pending_segments:
|
|
160
|
+
return self._pending_segments[start_sequence_number]
|
|
161
|
+
|
|
162
|
+
segmented_packet = SegmentedPacket(
|
|
163
|
+
total_length=total_length, total_payload=bytearray(total_length)
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
self._pending_segments[start_sequence_number] = segmented_packet
|
|
167
|
+
|
|
168
|
+
return segmented_packet
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import struct
|
|
3
|
+
import sys
|
|
4
|
+
from albibong.photon_packet_parser.protocol16_type import Protocol16Type
|
|
5
|
+
from albibong.photon_packet_parser.operation_request import OperationRequest
|
|
6
|
+
from albibong.photon_packet_parser.operation_response import OperationResponse
|
|
7
|
+
from albibong.photon_packet_parser.event_data import EventData
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Protocol16Deserializer:
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def deserialize(input: io.BytesIO, type_code: int):
|
|
14
|
+
if (
|
|
15
|
+
type_code == Protocol16Type.UNKNOWN.value
|
|
16
|
+
or type_code == Protocol16Type.NULL.value
|
|
17
|
+
):
|
|
18
|
+
return None
|
|
19
|
+
elif type_code == Protocol16Type.DICTIONARY.value:
|
|
20
|
+
return Protocol16Deserializer.deserialize_dictionary(input)
|
|
21
|
+
elif type_code == Protocol16Type.STRINGARRAY.value:
|
|
22
|
+
return Protocol16Deserializer.deserialize_string_array(input)
|
|
23
|
+
elif type_code == Protocol16Type.BYTE.value:
|
|
24
|
+
return Protocol16Deserializer.deserialize_byte(input)
|
|
25
|
+
elif type_code == Protocol16Type.DOUBLE.value:
|
|
26
|
+
return Protocol16Deserializer.deserialize_double(input)
|
|
27
|
+
elif type_code == Protocol16Type.EVENTDATA.value:
|
|
28
|
+
return Protocol16Deserializer.deserialize_event_data(input)
|
|
29
|
+
elif type_code == Protocol16Type.FLOAT.value:
|
|
30
|
+
return Protocol16Deserializer.deserialize_float(input)
|
|
31
|
+
elif type_code == Protocol16Type.INTEGER.value:
|
|
32
|
+
return Protocol16Deserializer.deserialize_integer(input)
|
|
33
|
+
elif type_code == Protocol16Type.HASHTABLE.value:
|
|
34
|
+
return Protocol16Deserializer.deserialize_hash_table(input)
|
|
35
|
+
elif type_code == Protocol16Type.SHORT.value:
|
|
36
|
+
return Protocol16Deserializer.deserialize_short(input)
|
|
37
|
+
elif type_code == Protocol16Type.LONG.value:
|
|
38
|
+
return Protocol16Deserializer.deserialize_long(input)
|
|
39
|
+
elif type_code == Protocol16Type.INTEGERARRAY.value:
|
|
40
|
+
return Protocol16Deserializer.deserialize_integer_array(input)
|
|
41
|
+
elif type_code == Protocol16Type.BOOLEAN.value:
|
|
42
|
+
return Protocol16Deserializer.deserialize_boolean(input)
|
|
43
|
+
elif type_code == Protocol16Type.OPERATIONRESPONSE.value:
|
|
44
|
+
return Protocol16Deserializer.deserialize_operation_response(input)
|
|
45
|
+
elif type_code == Protocol16Type.OPERATIONREQUEST.value:
|
|
46
|
+
return Protocol16Deserializer.deserialize_operation_request(input)
|
|
47
|
+
elif type_code == Protocol16Type.STRING.value:
|
|
48
|
+
return Protocol16Deserializer.deserialize_string(input)
|
|
49
|
+
elif type_code == Protocol16Type.BYTEARRAY.value:
|
|
50
|
+
return Protocol16Deserializer.deserialize_byte_array(input)
|
|
51
|
+
elif type_code == Protocol16Type.ARRAY.value:
|
|
52
|
+
return Protocol16Deserializer.deserialize_array(input)
|
|
53
|
+
elif type_code == Protocol16Type.OBJECTARRAY.value:
|
|
54
|
+
return Protocol16Deserializer.deserialize_object_array(input)
|
|
55
|
+
else:
|
|
56
|
+
raise Exception("Unknown type code: " + str(type_code))
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def deserialize_operation_request(input: io.BytesIO):
|
|
60
|
+
code = Protocol16Deserializer.deserialize_byte(input)
|
|
61
|
+
table = Protocol16Deserializer.deserialize_parameter_table(input)
|
|
62
|
+
return OperationRequest(code, table)
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def deserialize_operation_response(input: io.BytesIO):
|
|
66
|
+
code = Protocol16Deserializer.deserialize_byte(input)
|
|
67
|
+
return_code = Protocol16Deserializer.deserialize_short(input)
|
|
68
|
+
debug_message = Protocol16Deserializer.deserialize(
|
|
69
|
+
input, Protocol16Deserializer.deserialize_byte(input)
|
|
70
|
+
)
|
|
71
|
+
parameters = Protocol16Deserializer.deserialize_parameter_table(input)
|
|
72
|
+
return OperationResponse(code, return_code, debug_message, parameters)
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
def deserialize_event_data(input: io.BytesIO):
|
|
76
|
+
code = Protocol16Deserializer.deserialize_byte(input)
|
|
77
|
+
parameters = Protocol16Deserializer.deserialize_parameter_table(input)
|
|
78
|
+
return EventData(code, parameters)
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def deserialize_parameter_table(input):
|
|
82
|
+
dictionary_size = Protocol16Deserializer.deserialize_short(input)
|
|
83
|
+
dictionary = {}
|
|
84
|
+
|
|
85
|
+
for _ in range(dictionary_size):
|
|
86
|
+
key = Protocol16Deserializer.deserialize_byte(input)
|
|
87
|
+
value_type_code = Protocol16Deserializer.deserialize_byte(input)
|
|
88
|
+
value = Protocol16Deserializer.deserialize(input, value_type_code)
|
|
89
|
+
dictionary[key] = value
|
|
90
|
+
|
|
91
|
+
return dictionary
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def deserialize_short(input: io.BytesIO):
|
|
95
|
+
buffer = input.read(2)
|
|
96
|
+
return struct.unpack(">h", buffer)[0]
|
|
97
|
+
|
|
98
|
+
@staticmethod
|
|
99
|
+
def deserialize_byte(input: io.BytesIO):
|
|
100
|
+
return input.read(1)[0]
|
|
101
|
+
|
|
102
|
+
@staticmethod
|
|
103
|
+
def deserialize_boolean(input: io.BytesIO):
|
|
104
|
+
return input.read(1)[0] != 0
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def deserialize_integer(input: io.BytesIO):
|
|
108
|
+
buffer = input.read(4)
|
|
109
|
+
return struct.unpack(">i", buffer)[0]
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
def deserialize_long(input: io.BytesIO):
|
|
113
|
+
buffer = input.read(8)
|
|
114
|
+
|
|
115
|
+
if sys.byteorder == "little":
|
|
116
|
+
return struct.unpack(">q", buffer)[0]
|
|
117
|
+
|
|
118
|
+
return struct.unpack("<q", buffer)[0]
|
|
119
|
+
|
|
120
|
+
@staticmethod
|
|
121
|
+
def deserialize_float(input: io.BytesIO):
|
|
122
|
+
buffer = input.read(4)
|
|
123
|
+
|
|
124
|
+
if sys.byteorder == "little":
|
|
125
|
+
return struct.unpack(">f", buffer)[0]
|
|
126
|
+
|
|
127
|
+
return struct.unpack("<f", buffer)[0]
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def deserialize_double(input: io.BytesIO):
|
|
131
|
+
buffer = input.read(8)
|
|
132
|
+
|
|
133
|
+
if sys.byteorder == "little":
|
|
134
|
+
return struct.unpack(">d", buffer)[0]
|
|
135
|
+
|
|
136
|
+
return struct.unpack("<d", buffer)[0]
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
def deserialize_string(input: io.BytesIO):
|
|
140
|
+
string_size = Protocol16Deserializer.deserialize_short(input)
|
|
141
|
+
|
|
142
|
+
if string_size == 0:
|
|
143
|
+
return ""
|
|
144
|
+
|
|
145
|
+
buffer = input.read(string_size)
|
|
146
|
+
return buffer.decode("utf-8")
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def deserialize_byte_array(input: io.BytesIO):
|
|
150
|
+
array_size = Protocol16Deserializer.deserialize_integer(input)
|
|
151
|
+
|
|
152
|
+
array = []
|
|
153
|
+
for _ in range(array_size):
|
|
154
|
+
tmp = Protocol16Deserializer.deserialize_byte(input)
|
|
155
|
+
array.append(tmp)
|
|
156
|
+
|
|
157
|
+
return array
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def deserialize_integer_array(input: io.BytesIO):
|
|
161
|
+
array_size = Protocol16Deserializer.deserialize_integer(input)
|
|
162
|
+
|
|
163
|
+
array = []
|
|
164
|
+
for _ in range(array_size):
|
|
165
|
+
tmp = Protocol16Deserializer.deserialize_integer(input)
|
|
166
|
+
array.append(tmp)
|
|
167
|
+
|
|
168
|
+
return array
|
|
169
|
+
|
|
170
|
+
@staticmethod
|
|
171
|
+
def deserialize_string_array(input: io.BytesIO):
|
|
172
|
+
array_size = Protocol16Deserializer.deserialize_short(input)
|
|
173
|
+
|
|
174
|
+
array = []
|
|
175
|
+
for _ in range(array_size):
|
|
176
|
+
tmp = Protocol16Deserializer.deserialize_string(input)
|
|
177
|
+
array.append(tmp)
|
|
178
|
+
|
|
179
|
+
return array
|
|
180
|
+
|
|
181
|
+
@staticmethod
|
|
182
|
+
def deserialize_object_array(input: io.BytesIO):
|
|
183
|
+
array_size = Protocol16Deserializer.deserialize_short(input)
|
|
184
|
+
|
|
185
|
+
array = []
|
|
186
|
+
for _ in range(array_size):
|
|
187
|
+
typeCode = Protocol16Deserializer.deserialize_byte(input)
|
|
188
|
+
tmp = Protocol16Deserializer.deserialize(input, typeCode)
|
|
189
|
+
array.append(tmp)
|
|
190
|
+
|
|
191
|
+
return array
|
|
192
|
+
|
|
193
|
+
@staticmethod
|
|
194
|
+
def deserialize_array(input: io.BytesIO):
|
|
195
|
+
array_size = Protocol16Deserializer.deserialize_short(input)
|
|
196
|
+
type_code = Protocol16Deserializer.deserialize_byte(input)
|
|
197
|
+
|
|
198
|
+
if type_code == Protocol16Type.ARRAY.value:
|
|
199
|
+
result = []
|
|
200
|
+
for _ in range(0, array_size):
|
|
201
|
+
tmp = Protocol16Deserializer.deserialize_array(input)
|
|
202
|
+
result.append(tmp)
|
|
203
|
+
|
|
204
|
+
return result
|
|
205
|
+
elif type_code == Protocol16Type.BYTEARRAY.value:
|
|
206
|
+
result = []
|
|
207
|
+
for _ in range(array_size):
|
|
208
|
+
tmp = Protocol16Deserializer.deserialize_byte_array(input)
|
|
209
|
+
result.append(tmp)
|
|
210
|
+
|
|
211
|
+
return result
|
|
212
|
+
elif type_code == Protocol16Type.DICTIONARY.value:
|
|
213
|
+
return Protocol16Deserializer.deserialize_dictionary_array(
|
|
214
|
+
input, array_size
|
|
215
|
+
)
|
|
216
|
+
else:
|
|
217
|
+
result = []
|
|
218
|
+
for _ in range(array_size):
|
|
219
|
+
tmp = Protocol16Deserializer.deserialize(input, type_code)
|
|
220
|
+
result.append(tmp)
|
|
221
|
+
|
|
222
|
+
return result
|
|
223
|
+
|
|
224
|
+
@staticmethod
|
|
225
|
+
def deserialize_dictionary(input: io.BytesIO):
|
|
226
|
+
key_type_code = Protocol16Deserializer.deserialize_byte(input)
|
|
227
|
+
value_type_code = Protocol16Deserializer.deserialize_byte(input)
|
|
228
|
+
dictionary_size = Protocol16Deserializer.deserialize_short(input)
|
|
229
|
+
return Protocol16Deserializer.deserialize_dictionary_elements(
|
|
230
|
+
input, dictionary_size, key_type_code, value_type_code
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
@staticmethod
|
|
234
|
+
def deserialize_dictionary_elements(
|
|
235
|
+
input: io.BytesIO,
|
|
236
|
+
dictionary_size: int,
|
|
237
|
+
key_type_code: int,
|
|
238
|
+
value_type_code: int,
|
|
239
|
+
):
|
|
240
|
+
output = {}
|
|
241
|
+
for _ in range(dictionary_size):
|
|
242
|
+
key = Protocol16Deserializer.deserialize(
|
|
243
|
+
input,
|
|
244
|
+
(
|
|
245
|
+
Protocol16Deserializer.deserialize_byte(input)
|
|
246
|
+
if key_type_code == 0 or key_type_code == 42
|
|
247
|
+
else key_type_code
|
|
248
|
+
),
|
|
249
|
+
)
|
|
250
|
+
value = Protocol16Deserializer.deserialize(
|
|
251
|
+
input,
|
|
252
|
+
(
|
|
253
|
+
Protocol16Deserializer.deserialize_byte(input)
|
|
254
|
+
if value_type_code == 0 or value_type_code == 42
|
|
255
|
+
else value_type_code
|
|
256
|
+
),
|
|
257
|
+
)
|
|
258
|
+
output[key] = value
|
|
259
|
+
|
|
260
|
+
return output
|
|
261
|
+
|
|
262
|
+
@staticmethod
|
|
263
|
+
def deserialize_dictionary_array(input: io.BytesIO, size: int):
|
|
264
|
+
key_type_code = Protocol16Deserializer.deserialize_byte(input)
|
|
265
|
+
value_type_code = Protocol16Deserializer.deserialize_byte(input)
|
|
266
|
+
output = []
|
|
267
|
+
|
|
268
|
+
for _ in range(size):
|
|
269
|
+
dictionary_size = Protocol16Deserializer.deserialize_short(input)
|
|
270
|
+
|
|
271
|
+
dictionary = {}
|
|
272
|
+
for _ in range(dictionary_size):
|
|
273
|
+
key = None
|
|
274
|
+
if key_type_code > 0:
|
|
275
|
+
key = Protocol16Deserializer.deserialize(input, key_type_code)
|
|
276
|
+
else:
|
|
277
|
+
next_key_type_code = Protocol16Deserializer.deserialize_byte(input)
|
|
278
|
+
key = Protocol16Deserializer.deserialize(input, next_key_type_code)
|
|
279
|
+
|
|
280
|
+
value = None
|
|
281
|
+
if value_type_code > 0:
|
|
282
|
+
value = Protocol16Deserializer.deserialize(input, value_type_code)
|
|
283
|
+
else:
|
|
284
|
+
next_value_type_code = Protocol16Deserializer.deserialize_byte(
|
|
285
|
+
input
|
|
286
|
+
)
|
|
287
|
+
value = Protocol16Deserializer.deserialize(
|
|
288
|
+
input, next_value_type_code
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
dictionary[key] = value
|
|
292
|
+
|
|
293
|
+
output.append(dictionary)
|
|
294
|
+
|
|
295
|
+
return output
|
|
296
|
+
|
|
297
|
+
@staticmethod
|
|
298
|
+
def deserialize_hash_table(input: io.BytesIO):
|
|
299
|
+
size = Protocol16Deserializer.deserialize_short(input)
|
|
300
|
+
return Protocol16Deserializer.deserialize_dictionary_elements(
|
|
301
|
+
input, size, Protocol16Type.UNKNOWN, Protocol16Type.UNKNOWN
|
|
302
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
class Protocol16Type(Enum):
|
|
4
|
+
UNKNOWN = 0
|
|
5
|
+
NULL = 42
|
|
6
|
+
DICTIONARY = 68
|
|
7
|
+
STRINGARRAY = 97
|
|
8
|
+
BYTE = 98
|
|
9
|
+
DOUBLE = 100
|
|
10
|
+
EVENTDATA = 101
|
|
11
|
+
FLOAT = 102
|
|
12
|
+
INTEGER = 105
|
|
13
|
+
HASHTABLE = 104
|
|
14
|
+
SHORT = 107
|
|
15
|
+
LONG = 108
|
|
16
|
+
INTEGERARRAY = 110
|
|
17
|
+
BOOLEAN = 111
|
|
18
|
+
OPERATIONRESPONSE = 112
|
|
19
|
+
OPERATIONREQUEST = 113
|
|
20
|
+
STRING = 115
|
|
21
|
+
BYTEARRAY = 120
|
|
22
|
+
ARRAY = 121
|
|
23
|
+
OBJECTARRAY = 122
|