litenetlib-0952 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.
- litenetlib/__init__.py +66 -0
- litenetlib/channels/__init__.py +16 -0
- litenetlib/channels/base_channel.py +115 -0
- litenetlib/channels/reliable_channel.py +451 -0
- litenetlib/channels/sequenced_channel.py +239 -0
- litenetlib/core/__init__.py +53 -0
- litenetlib/core/connection_request.py +240 -0
- litenetlib/core/constants.py +186 -0
- litenetlib/core/events.py +336 -0
- litenetlib/core/internal_packets.py +358 -0
- litenetlib/core/manager.py +355 -0
- litenetlib/core/packet.py +457 -0
- litenetlib/core/peer.py +334 -0
- litenetlib/utils/__init__.py +21 -0
- litenetlib/utils/data_reader.py +447 -0
- litenetlib/utils/data_writer.py +402 -0
- litenetlib/utils/fast_bit_converter.py +199 -0
- litenetlib/utils/net_utils.py +165 -0
- litenetlib_0952-1.0.0.dist-info/METADATA +448 -0
- litenetlib_0952-1.0.0.dist-info/RECORD +23 -0
- litenetlib_0952-1.0.0.dist-info/WHEEL +5 -0
- litenetlib_0952-1.0.0.dist-info/licenses/LICENSE +21 -0
- litenetlib_0952-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Internal connection packets for LiteNetLib v0.9.5.2 protocol.
|
|
3
|
+
LiteNetLib v0.9.5.2 内部连接数据包
|
|
4
|
+
|
|
5
|
+
This module contains the internal packet structures used for connection
|
|
6
|
+
establishment and management. These packets are part of the core protocol
|
|
7
|
+
and must match the C# implementation byte-for-byte.
|
|
8
|
+
|
|
9
|
+
本模块包含用于连接建立和管理的内部数据包结构。
|
|
10
|
+
这些数据包是核心协议的一部分,必须与 C# 实现逐字节匹配。
|
|
11
|
+
|
|
12
|
+
Ported from: LiteNetLib/NetPacket.cs (v0.9.5.2)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import struct
|
|
16
|
+
import socket
|
|
17
|
+
from typing import Optional, Tuple
|
|
18
|
+
from litenetlib.core.constants import NetConstants, PacketProperty
|
|
19
|
+
from litenetlib.core.packet import NetPacket
|
|
20
|
+
from litenetlib.utils.fast_bit_converter import FastBitConverter
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class NetConnectRequestPacket:
|
|
24
|
+
"""
|
|
25
|
+
Connection request packet / 连接请求数据包
|
|
26
|
+
|
|
27
|
+
Sent by client to server when initiating a connection.
|
|
28
|
+
客户端向服务器发起连接时发送。
|
|
29
|
+
|
|
30
|
+
C# Reference: NetConnectRequestPacket (v0.9.5.2)
|
|
31
|
+
Structure (HeaderSize = 14) / 结构:
|
|
32
|
+
- Byte 0: Property (ConnectRequest) + connNum / 属性 + 连接号
|
|
33
|
+
- Bytes 1-4: ProtocolId (int, little-endian) = 11 / 协议 ID
|
|
34
|
+
- Bytes 5-12: ConnectionTime (long, little-endian) / 连接时间
|
|
35
|
+
- Byte 13: Address size (16 for IPv4, 28 for IPv6) / 地址大小
|
|
36
|
+
- Bytes 14+: Target address bytes / 目标地址字节
|
|
37
|
+
- Bytes 14+addrSize+: Additional connection data / 额外连接数据
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
HEADER_SIZE = 14
|
|
41
|
+
|
|
42
|
+
__slots__ = ('connection_time', 'connection_number', 'target_address', 'data')
|
|
43
|
+
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
connection_time: int,
|
|
47
|
+
connection_number: int,
|
|
48
|
+
target_address: bytes,
|
|
49
|
+
data: Optional[bytes] = None
|
|
50
|
+
):
|
|
51
|
+
"""
|
|
52
|
+
Create connection request packet / 创建连接请求数据包。
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
connection_time: Connection timestamp (long, ticks) / 连接时间戳
|
|
56
|
+
connection_number: Connection number (0-3) / 连接编号
|
|
57
|
+
target_address: Serialized target address bytes / 序列化的目标地址字节
|
|
58
|
+
data: Additional connection data / 额外连接数据
|
|
59
|
+
"""
|
|
60
|
+
self.connection_time = connection_time
|
|
61
|
+
self.connection_number = connection_number
|
|
62
|
+
self.target_address = target_address
|
|
63
|
+
self.data = data or b''
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def get_protocol_id(packet: NetPacket) -> int:
|
|
67
|
+
"""
|
|
68
|
+
Extract protocol ID from connection request packet.
|
|
69
|
+
从连接请求数据包中提取协议 ID。
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
packet: Connection request packet / 连接请求数据包
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Protocol ID (should be 11 for v0.9.5.2) / 协议 ID(v0.9.5.2 应为 11)
|
|
76
|
+
|
|
77
|
+
C# Equivalent: GetProtocolId(NetPacket packet)
|
|
78
|
+
"""
|
|
79
|
+
# C#: BitConverter.ToInt32(packet.RawData, 1)
|
|
80
|
+
return struct.unpack_from('<I', packet._data, 1)[0]
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def from_data(packet: NetPacket) -> Optional['NetConnectRequestPacket']:
|
|
84
|
+
"""
|
|
85
|
+
Parse connection request from packet / 从数据包解析连接请求。
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
packet: Received packet / 接收到的数据包
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Parsed connection request, or None if invalid / 解析的连接请求,无效则返回 None
|
|
92
|
+
|
|
93
|
+
C# Equivalent: FromData(NetPacket packet)
|
|
94
|
+
"""
|
|
95
|
+
conn_num = packet.connection_number
|
|
96
|
+
if conn_num >= NetConstants.MAX_CONNECTION_NUMBER:
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
# Get connection time (long at offset 5)
|
|
100
|
+
# C#: BitConverter.ToInt64(packet.RawData, 5)
|
|
101
|
+
connection_time = struct.unpack_from('<q', packet._data, 5)[0]
|
|
102
|
+
|
|
103
|
+
# Get target address size (byte at offset 13)
|
|
104
|
+
# C#: int addrSize = packet.RawData[13]
|
|
105
|
+
addr_size = packet._data[13]
|
|
106
|
+
if addr_size != 16 and addr_size != 28:
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
# Extract target address bytes
|
|
110
|
+
# C#: Buffer.BlockCopy(packet.RawData, 14, addressBytes, 0, addrSize)
|
|
111
|
+
if packet.size < NetConnectRequestPacket.HEADER_SIZE + addr_size:
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
address_bytes = bytes(packet._data[
|
|
115
|
+
NetConnectRequestPacket.HEADER_SIZE:
|
|
116
|
+
NetConnectRequestPacket.HEADER_SIZE + addr_size
|
|
117
|
+
])
|
|
118
|
+
|
|
119
|
+
# Extract additional data if present
|
|
120
|
+
# C#: reader.SetSource(packet.RawData, HeaderSize + addrSize, packet.Size)
|
|
121
|
+
data = b''
|
|
122
|
+
if packet.size > NetConnectRequestPacket.HEADER_SIZE + addr_size:
|
|
123
|
+
data = bytes(packet._data[
|
|
124
|
+
NetConnectRequestPacket.HEADER_SIZE + addr_size:
|
|
125
|
+
packet.size
|
|
126
|
+
])
|
|
127
|
+
|
|
128
|
+
return NetConnectRequestPacket(
|
|
129
|
+
connection_time=connection_time,
|
|
130
|
+
connection_number=conn_num,
|
|
131
|
+
target_address=address_bytes,
|
|
132
|
+
data=data
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
@staticmethod
|
|
136
|
+
def make(
|
|
137
|
+
connect_data: bytes,
|
|
138
|
+
address_bytes: bytes,
|
|
139
|
+
connect_id: int
|
|
140
|
+
) -> NetPacket:
|
|
141
|
+
"""
|
|
142
|
+
Create connection request packet / 创建连接请求数据包。
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
connect_data: Additional connection data to send / 要发送的额外连接数据
|
|
146
|
+
address_bytes: Serialized target address (SocketAddress) / 序列化的目标地址
|
|
147
|
+
connect_id: Connection ID / 连接 ID
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Constructed packet ready to send / 构造好的可发送数据包
|
|
151
|
+
|
|
152
|
+
C# Equivalent: Make(NetDataWriter, SocketAddress, long)
|
|
153
|
+
"""
|
|
154
|
+
# Create initial packet with space for data
|
|
155
|
+
# C#: var packet = new NetPacket(PacketProperty.ConnectRequest, connectData.Length+addressBytes.Size)
|
|
156
|
+
packet = NetPacket(PacketProperty.CONNECT_REQUEST, len(connect_data) + len(address_bytes))
|
|
157
|
+
|
|
158
|
+
# Write protocol ID (offset 1)
|
|
159
|
+
# C#: FastBitConverter.GetBytes(packet.RawData, 1, NetConstants.ProtocolId)
|
|
160
|
+
FastBitConverter.get_bytes_uint(packet._data, 1, NetConstants.PROTOCOL_ID)
|
|
161
|
+
|
|
162
|
+
# Write connection ID (offset 5)
|
|
163
|
+
# C#: FastBitConverter.GetBytes(packet.RawData, 5, connectId)
|
|
164
|
+
FastBitConverter.get_bytes_long(packet._data, 5, connect_id)
|
|
165
|
+
|
|
166
|
+
# Write address size (offset 13)
|
|
167
|
+
# C#: packet.RawData[13] = (byte)addressBytes.Size
|
|
168
|
+
packet._data[13] = len(address_bytes) & 0xFF
|
|
169
|
+
|
|
170
|
+
# Write address bytes
|
|
171
|
+
# C#: for (int i = 0; i < addressBytes.Size; i++) packet.RawData[14+i] = addressBytes[i]
|
|
172
|
+
addr_start = NetConnectRequestPacket.HEADER_SIZE
|
|
173
|
+
packet._data[addr_start:addr_start + len(address_bytes)] = address_bytes
|
|
174
|
+
|
|
175
|
+
# Write connection data
|
|
176
|
+
# C#: Buffer.BlockCopy(connectData.Data, 0, packet.RawData, 14+addressBytes.Size, connectData.Length)
|
|
177
|
+
if connect_data:
|
|
178
|
+
data_start = addr_start + len(address_bytes)
|
|
179
|
+
packet._data[data_start:data_start + len(connect_data)] = connect_data
|
|
180
|
+
|
|
181
|
+
return packet
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class NetConnectAcceptPacket:
|
|
185
|
+
"""
|
|
186
|
+
Connection accept packet / 连接接受数据包
|
|
187
|
+
|
|
188
|
+
Sent by server to client to accept a connection.
|
|
189
|
+
服务器向客户端发送以接受连接。
|
|
190
|
+
|
|
191
|
+
C# Reference: NetConnectAcceptPacket (v0.9.5.2)
|
|
192
|
+
Structure (Size = 11) / 结构:
|
|
193
|
+
- Byte 0: Property (ConnectAccept) / 属性
|
|
194
|
+
- Bytes 1-8: ConnectionId (long, little-endian) / 连接 ID
|
|
195
|
+
- Byte 9: ConnectionNumber (0-3) / 连接编号
|
|
196
|
+
- Byte 10: IsReused (0 or 1) / 是否重用
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
SIZE = 11
|
|
200
|
+
|
|
201
|
+
__slots__ = ('connection_id', 'connection_number', 'is_reused')
|
|
202
|
+
|
|
203
|
+
def __init__(
|
|
204
|
+
self,
|
|
205
|
+
connection_id: int,
|
|
206
|
+
connection_number: int,
|
|
207
|
+
is_reused: bool = False
|
|
208
|
+
):
|
|
209
|
+
"""
|
|
210
|
+
Create connection accept packet / 创建连接接受数据包。
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
connection_id: Connection ID (long) / 连接 ID
|
|
214
|
+
connection_number: Connection number (0-3) / 连接编号
|
|
215
|
+
is_reused: Whether peer ID was reused / 是否重用了对等端 ID
|
|
216
|
+
"""
|
|
217
|
+
self.connection_id = connection_id
|
|
218
|
+
self.connection_number = connection_number
|
|
219
|
+
self.is_reused = is_reused
|
|
220
|
+
|
|
221
|
+
@staticmethod
|
|
222
|
+
def from_data(packet: NetPacket) -> Optional['NetConnectAcceptPacket']:
|
|
223
|
+
"""
|
|
224
|
+
Parse connection accept from packet / 从数据包解析连接接受。
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
packet: Received packet / 接收到的数据包
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
Parsed connection accept, or None if invalid / 解析的连接接受,无效则返回 None
|
|
231
|
+
|
|
232
|
+
C# Equivalent: FromData(NetPacket packet)
|
|
233
|
+
"""
|
|
234
|
+
if packet.size > NetConnectAcceptPacket.SIZE:
|
|
235
|
+
return None
|
|
236
|
+
|
|
237
|
+
# Get connection ID (long at offset 1)
|
|
238
|
+
# C#: long connectionId = BitConverter.ToInt64(packet.RawData, 1)
|
|
239
|
+
connection_id = struct.unpack_from('<q', packet._data, 1)[0]
|
|
240
|
+
|
|
241
|
+
# Get connection number (byte at offset 9)
|
|
242
|
+
# C#: byte connectionNumber = packet.RawData[9]
|
|
243
|
+
connection_number = packet._data[9]
|
|
244
|
+
if connection_number >= NetConstants.MAX_CONNECTION_NUMBER:
|
|
245
|
+
return None
|
|
246
|
+
|
|
247
|
+
# Get reuse flag (byte at offset 10)
|
|
248
|
+
# C#: byte isReused = packet.RawData[10]
|
|
249
|
+
is_reused = packet._data[10]
|
|
250
|
+
if is_reused > 1:
|
|
251
|
+
return None
|
|
252
|
+
|
|
253
|
+
return NetConnectAcceptPacket(
|
|
254
|
+
connection_id=connection_id,
|
|
255
|
+
connection_number=connection_number,
|
|
256
|
+
is_reused=(is_reused == 1)
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
@staticmethod
|
|
260
|
+
def make(
|
|
261
|
+
connect_id: int,
|
|
262
|
+
connect_num: int,
|
|
263
|
+
reused_peer: bool = False
|
|
264
|
+
) -> NetPacket:
|
|
265
|
+
"""
|
|
266
|
+
Create connection accept packet / 创建连接接受数据包。
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
connect_id: Connection ID (long) / 连接 ID
|
|
270
|
+
connect_num: Connection number (0-3) / 连接编号
|
|
271
|
+
reused_peer: Whether this is a reused peer / 是否为重用的对等端
|
|
272
|
+
|
|
273
|
+
Returns:
|
|
274
|
+
Constructed packet ready to send / 构造好的可发送数据包
|
|
275
|
+
|
|
276
|
+
C# Equivalent: Make(long, byte, bool)
|
|
277
|
+
"""
|
|
278
|
+
# Create packet (no additional data needed)
|
|
279
|
+
# C#: var packet = new NetPacket(PacketProperty.ConnectAccept, 0)
|
|
280
|
+
packet = NetPacket(PacketProperty.CONNECT_ACCEPT, 0)
|
|
281
|
+
|
|
282
|
+
# Write connection ID (offset 1)
|
|
283
|
+
# C#: FastBitConverter.GetBytes(packet.RawData, 1, connectId)
|
|
284
|
+
FastBitConverter.get_bytes_long(packet._data, 1, connect_id)
|
|
285
|
+
|
|
286
|
+
# Write connection number (offset 9)
|
|
287
|
+
# C#: packet.RawData[9] = connectNum
|
|
288
|
+
packet._data[9] = connect_num & 0xFF
|
|
289
|
+
|
|
290
|
+
# Write reuse flag (offset 10)
|
|
291
|
+
# C#: packet.RawData[10] = (byte)(reusedPeer ? 1 : 0)
|
|
292
|
+
packet._data[10] = 1 if reused_peer else 0
|
|
293
|
+
|
|
294
|
+
return packet
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
# Helper functions for address serialization / 地址序列化辅助函数
|
|
298
|
+
|
|
299
|
+
def serialize_address(host: str, port: int) -> bytes:
|
|
300
|
+
"""
|
|
301
|
+
Serialize an IP address and port to bytes.
|
|
302
|
+
将 IP 地址和端口序列化为字节。
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
host: IP address string / IP 地址字符串
|
|
306
|
+
port: Port number / 端口号
|
|
307
|
+
|
|
308
|
+
Returns:
|
|
309
|
+
Serialized address bytes (SocketAddress format) / 序列化的地址字节
|
|
310
|
+
|
|
311
|
+
C# Equivalent: SocketAddress serialization
|
|
312
|
+
"""
|
|
313
|
+
try:
|
|
314
|
+
# Try IPv4 first / 先尝试 IPv4
|
|
315
|
+
addr_bytes = socket.inet_pton(socket.AF_INET, host)
|
|
316
|
+
# Format for IPv4: [4 bytes address][2 bytes port]
|
|
317
|
+
# IPv4 格式:[4 字节地址][2 字节端口]
|
|
318
|
+
return addr_bytes + struct.pack('<H', port)
|
|
319
|
+
except socket.error:
|
|
320
|
+
try:
|
|
321
|
+
# Try IPv6 / 尝试 IPv6
|
|
322
|
+
addr_bytes = socket.inet_pton(socket.AF_INET6, host)
|
|
323
|
+
# Format for IPv6: [16 bytes address][2 bytes port]
|
|
324
|
+
# IPv6 格式:[16 字节地址][2 字节端口]
|
|
325
|
+
return addr_bytes + struct.pack('<H', port)
|
|
326
|
+
except socket.error:
|
|
327
|
+
raise ValueError(f"Invalid address: {host}")
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def deserialize_address(data: bytes, offset: int = 0) -> Tuple[str, int, str]:
|
|
331
|
+
"""
|
|
332
|
+
Deserialize an IP address and port from bytes.
|
|
333
|
+
从字节反序列化 IP 地址和端口。
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
data: Serialized address bytes / 序列化的地址字节
|
|
337
|
+
offset: Starting offset in data / 数据中的起始偏移
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
Tuple of (host, port, family) where family is 'IPv4' or 'IPv6'
|
|
341
|
+
(主机, 端口, 协议族) 元组,协议族为 'IPv4' 或 'IPv6'
|
|
342
|
+
|
|
343
|
+
C# Equivalent: SocketAddress deserialization
|
|
344
|
+
"""
|
|
345
|
+
# Determine format from size / 根据大小确定格式
|
|
346
|
+
size = len(data) - offset
|
|
347
|
+
if size == 6:
|
|
348
|
+
# IPv4: 4 bytes + 2 bytes port / IPv4:4 字节 + 2 字节端口
|
|
349
|
+
host = socket.inet_ntop(socket.AF_INET, data[offset:offset+4])
|
|
350
|
+
port = struct.unpack_from('<H', data, offset + 4)[0]
|
|
351
|
+
return host, port, 'IPv4'
|
|
352
|
+
elif size == 18:
|
|
353
|
+
# IPv6: 16 bytes + 2 bytes port / IPv6:16 字节 + 2 字节端口
|
|
354
|
+
host = socket.inet_ntop(socket.AF_INET6, data[offset:offset+16])
|
|
355
|
+
port = struct.unpack_from('<H', data, offset + 16)[0]
|
|
356
|
+
return host, port, 'IPv6'
|
|
357
|
+
else:
|
|
358
|
+
raise ValueError(f"Invalid serialized address size: {size}")
|