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.
@@ -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}")