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,355 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Network manager for LiteNetLib v0.9.5.2 / LiteNetLib v0.9.5.2 网络管理器
|
|
3
|
+
|
|
4
|
+
Main class for all network operations. Can be used as client and/or server.
|
|
5
|
+
所有网络操作的主类。可以用作客户端和/或服务器。
|
|
6
|
+
|
|
7
|
+
Ported from: LiteNetLib/NetManager.cs (v0.9.5.2)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import socket
|
|
12
|
+
import time
|
|
13
|
+
from typing import Dict, Optional, Set, Callable, Any
|
|
14
|
+
from litenetlib.core.constants import NetConstants, PacketProperty, DisconnectReason
|
|
15
|
+
from litenetlib.core.packet import NetPacket, NetPacketPool
|
|
16
|
+
from litenetlib.core.peer import NetPeer
|
|
17
|
+
from litenetlib.core.events import EventBasedNetListener, INetEventListener
|
|
18
|
+
from litenetlib.core.connection_request import ConnectionRequest
|
|
19
|
+
from litenetlib.utils.net_utils import NetUtils
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class LiteNetManager:
|
|
23
|
+
"""
|
|
24
|
+
Main network manager class / 主网络管理器类
|
|
25
|
+
|
|
26
|
+
Manages socket, peers, and network events.
|
|
27
|
+
管理 socket、对等端和网络事件。
|
|
28
|
+
|
|
29
|
+
C# Reference: NetManager
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, listener: Optional[INetEventListener] = None):
|
|
33
|
+
"""
|
|
34
|
+
Create network manager / 创建网络管理器。
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
listener: Event listener for network events / 网络事件监听器
|
|
38
|
+
"""
|
|
39
|
+
self._listener = listener
|
|
40
|
+
self._peers: Dict[tuple, NetPeer] = {}
|
|
41
|
+
self._socket: Optional[socket.socket] = None
|
|
42
|
+
self._running = False
|
|
43
|
+
self._packet_pool = NetPacketPool()
|
|
44
|
+
self._host: str = "0.0.0.0"
|
|
45
|
+
self._port: int = 0
|
|
46
|
+
self._max_peers: int = 10
|
|
47
|
+
self._auto_recycle = True
|
|
48
|
+
|
|
49
|
+
# Connection management / 连接管理
|
|
50
|
+
self._connect_time: int = 0
|
|
51
|
+
self._local_id: int = 0
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def peers_count(self) -> int:
|
|
55
|
+
"""Get number of connected peers / 获取已连接对等端数量"""
|
|
56
|
+
return len(self._peers)
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def is_running(self) -> bool:
|
|
60
|
+
"""Check if manager is running / 检查管理器是否正在运行"""
|
|
61
|
+
return self._running
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def local_port(self) -> int:
|
|
65
|
+
"""Get local port / 获取本地端口"""
|
|
66
|
+
return self._port
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def listener(self) -> Optional[INetEventListener]:
|
|
70
|
+
"""Get event listener / 获取事件监听器"""
|
|
71
|
+
return self._listener
|
|
72
|
+
|
|
73
|
+
@listener.setter
|
|
74
|
+
def listener(self, value: Optional[INetEventListener]) -> None:
|
|
75
|
+
"""Set event listener / 设置事件监听器"""
|
|
76
|
+
self._listener = value
|
|
77
|
+
|
|
78
|
+
def start(self, port: int = 0, host: str = "0.0.0.0", max_peers: int = 10) -> bool:
|
|
79
|
+
"""
|
|
80
|
+
Start network manager / 启动网络管理器。
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
port: Local port to bind to (0 for any available port) / 要绑定的本地端口
|
|
84
|
+
host: Local address to bind to / 要绑定的本地地址
|
|
85
|
+
max_peers: Maximum number of peers / 最大对等端数量
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
True if started successfully / 如果成功启动则返回 True
|
|
89
|
+
"""
|
|
90
|
+
if self._running:
|
|
91
|
+
return False
|
|
92
|
+
|
|
93
|
+
self._host = host
|
|
94
|
+
self._port = port
|
|
95
|
+
self._max_peers = max_peers
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
# Create UDP socket / 创建 UDP socket
|
|
99
|
+
self._socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
100
|
+
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
101
|
+
self._socket.bind((host, port))
|
|
102
|
+
|
|
103
|
+
# Get actual port if 0 was specified / 如果指定了 0,获取实际端口
|
|
104
|
+
if port == 0:
|
|
105
|
+
self._port = self._socket.getsockname()[1]
|
|
106
|
+
|
|
107
|
+
self._running = True
|
|
108
|
+
self._connect_time = NetUtils.get_time_ticks()
|
|
109
|
+
self._local_id = NetUtils.generate_connect_id()
|
|
110
|
+
|
|
111
|
+
return True
|
|
112
|
+
except Exception as e:
|
|
113
|
+
if self._socket:
|
|
114
|
+
self._socket.close()
|
|
115
|
+
self._socket = None
|
|
116
|
+
print(f"Failed to start manager: {e}")
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
def stop(self) -> None:
|
|
120
|
+
"""Stop network manager and disconnect all peers / 停止网络管理器并断开所有对等端"""
|
|
121
|
+
if not self._running:
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
# Disconnect all peers / 断开所有对等端
|
|
125
|
+
for peer in list(self._peers.values()):
|
|
126
|
+
peer.disconnect()
|
|
127
|
+
|
|
128
|
+
self._running = False
|
|
129
|
+
|
|
130
|
+
if self._socket:
|
|
131
|
+
self._socket.close()
|
|
132
|
+
self._socket = None
|
|
133
|
+
|
|
134
|
+
self._peers.clear()
|
|
135
|
+
|
|
136
|
+
def connect(self, host: str, port: int, connection_data: Optional[bytes] = None) -> bool:
|
|
137
|
+
"""
|
|
138
|
+
Connect to remote host / 连接到远程主机。
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
host: Remote host address / 远程主机地址
|
|
142
|
+
port: Remote port / 远程端口
|
|
143
|
+
connection_data: Optional connection data / 可选的连接数据
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
True if connection initiated successfully / 如果成功发起连接则返回 True
|
|
147
|
+
"""
|
|
148
|
+
if not self._running:
|
|
149
|
+
return False
|
|
150
|
+
|
|
151
|
+
address = (host, port)
|
|
152
|
+
if address in self._peers:
|
|
153
|
+
return False
|
|
154
|
+
|
|
155
|
+
# Create peer / 创建对等端
|
|
156
|
+
peer = NetPeer(self, address, 0)
|
|
157
|
+
self._peers[address] = peer
|
|
158
|
+
|
|
159
|
+
# Send connect request / 发送连接请求
|
|
160
|
+
peer.send_connect_request(connection_data or b'')
|
|
161
|
+
|
|
162
|
+
return True
|
|
163
|
+
|
|
164
|
+
def get_peer_by_address(self, host: str, port: int) -> Optional[NetPeer]:
|
|
165
|
+
"""
|
|
166
|
+
Get peer by address / 通过地址获取对等端。
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
host: Peer host address / 对等端主机地址
|
|
170
|
+
port: Peer port / 对等端端口
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
NetPeer if found, None otherwise / 找到则返回 NetPeer,否则返回 None
|
|
174
|
+
"""
|
|
175
|
+
return self._peers.get((host, port))
|
|
176
|
+
|
|
177
|
+
def send_to_all(
|
|
178
|
+
self,
|
|
179
|
+
data: bytes,
|
|
180
|
+
delivery_method: Any = None,
|
|
181
|
+
exclude_peer: Optional[NetPeer] = None
|
|
182
|
+
) -> None:
|
|
183
|
+
"""
|
|
184
|
+
Send data to all connected peers / 向所有已连接的对等端发送数据。
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
data: Data to send / 要发送的数据
|
|
188
|
+
delivery_method: Delivery method / 传输方法
|
|
189
|
+
exclude_peer: Peer to exclude from sending / 要排除的对等端
|
|
190
|
+
"""
|
|
191
|
+
for peer in self._peers.values():
|
|
192
|
+
if peer != exclude_peer and peer.is_connected:
|
|
193
|
+
peer.send(data, delivery_method)
|
|
194
|
+
|
|
195
|
+
async def poll_async(self) -> None:
|
|
196
|
+
"""
|
|
197
|
+
Async poll for network events / 异步轮询网络事件。
|
|
198
|
+
|
|
199
|
+
This method should be called in an async context to process network events.
|
|
200
|
+
此方法应在异步上下文中调用以处理网络事件。
|
|
201
|
+
"""
|
|
202
|
+
if not self._running or not self._socket:
|
|
203
|
+
return
|
|
204
|
+
|
|
205
|
+
try:
|
|
206
|
+
# Set socket to non-blocking / 设置 socket 为非阻塞
|
|
207
|
+
self._socket.setblocking(False)
|
|
208
|
+
|
|
209
|
+
while self._running:
|
|
210
|
+
try:
|
|
211
|
+
# Receive data / 接收数据
|
|
212
|
+
data, addr = self._socket.recvfrom(NetConstants.MAX_PACKET_SIZE)
|
|
213
|
+
await self._handle_packet(data, addr)
|
|
214
|
+
except BlockingIOError:
|
|
215
|
+
# No data available, wait a bit / 无可用数据,等待一下
|
|
216
|
+
await asyncio.sleep(0.001)
|
|
217
|
+
except Exception as e:
|
|
218
|
+
print(f"Error receiving data: {e}")
|
|
219
|
+
|
|
220
|
+
# Update peers / 更新对等端
|
|
221
|
+
current_time = NetUtils.get_time_millis()
|
|
222
|
+
for peer in list(self._peers.values()):
|
|
223
|
+
await peer.update_async(current_time)
|
|
224
|
+
|
|
225
|
+
except Exception as e:
|
|
226
|
+
print(f"Error in poll_async: {e}")
|
|
227
|
+
|
|
228
|
+
async def _handle_packet(self, data: bytes, addr: tuple) -> None:
|
|
229
|
+
"""
|
|
230
|
+
Handle received packet / 处理接收到的数据包。
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
data: Packet data / 数据包数据
|
|
234
|
+
addr: Sender address / 发送者地址
|
|
235
|
+
"""
|
|
236
|
+
try:
|
|
237
|
+
packet = NetPacket.from_bytes(data)
|
|
238
|
+
|
|
239
|
+
if not packet.verify():
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
peer = self._peers.get(addr)
|
|
243
|
+
|
|
244
|
+
# Handle packet based on property / 根据属性处理数据包
|
|
245
|
+
prop = packet.packet_property
|
|
246
|
+
|
|
247
|
+
if prop == PacketProperty.CONNECT_REQUEST:
|
|
248
|
+
await self._handle_connect_request(packet, addr)
|
|
249
|
+
elif prop == PacketProperty.CONNECT_ACCEPT:
|
|
250
|
+
if peer:
|
|
251
|
+
await peer.handle_connect_accept(packet)
|
|
252
|
+
elif prop == PacketProperty.DISCONNECT:
|
|
253
|
+
if peer:
|
|
254
|
+
await self._handle_disconnect(peer, packet)
|
|
255
|
+
elif prop == PacketProperty.ACK:
|
|
256
|
+
if peer:
|
|
257
|
+
await peer.handle_ack(packet)
|
|
258
|
+
elif prop in [PacketProperty.CHANNELED, PacketProperty.UNRELIABLE]:
|
|
259
|
+
if peer:
|
|
260
|
+
await peer.handle_data_packet(packet)
|
|
261
|
+
else:
|
|
262
|
+
# Other packet types / 其他数据包类型
|
|
263
|
+
if peer:
|
|
264
|
+
await peer.process_packet(packet)
|
|
265
|
+
|
|
266
|
+
except Exception as e:
|
|
267
|
+
print(f"Error handling packet from {addr}: {e}")
|
|
268
|
+
|
|
269
|
+
async def _handle_connect_request(self, packet: NetPacket, addr: tuple) -> None:
|
|
270
|
+
"""
|
|
271
|
+
Handle connection request / 处理连接请求。
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
packet: Connection request packet / 连接请求数据包
|
|
275
|
+
addr: Sender address / 发送者地址
|
|
276
|
+
"""
|
|
277
|
+
from litenetlib.core.internal_packets import NetConnectRequestPacket
|
|
278
|
+
|
|
279
|
+
request = NetConnectRequestPacket.from_data(packet)
|
|
280
|
+
if not request:
|
|
281
|
+
return
|
|
282
|
+
|
|
283
|
+
# Check if we can accept more peers / 检查是否可以接受更多对等端
|
|
284
|
+
if len(self._peers) >= self._max_peers:
|
|
285
|
+
# Send reject / 发送拒绝
|
|
286
|
+
self._send_reject(addr)
|
|
287
|
+
return
|
|
288
|
+
|
|
289
|
+
# Check protocol ID / 检查协议 ID
|
|
290
|
+
protocol_id = NetConnectRequestPacket.get_protocol_id(packet)
|
|
291
|
+
if protocol_id != NetConstants.PROTOCOL_ID:
|
|
292
|
+
# Send invalid protocol / 发送无效协议
|
|
293
|
+
self._send_invalid_protocol(addr)
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
# Create connection request event / 创建连接请求事件
|
|
297
|
+
conn_request = ConnectionRequest(self, addr, request)
|
|
298
|
+
|
|
299
|
+
if self._listener:
|
|
300
|
+
# Let listener decide / 让监听器决定
|
|
301
|
+
if self._listener.on_connection_request(conn_request):
|
|
302
|
+
# Accepted / 已接受
|
|
303
|
+
peer = NetPeer(self, addr, request.connection_number)
|
|
304
|
+
self._peers[addr] = peer
|
|
305
|
+
await peer.accept_connection(request)
|
|
306
|
+
else:
|
|
307
|
+
# Rejected / 已拒绝
|
|
308
|
+
conn_request.reject()
|
|
309
|
+
else:
|
|
310
|
+
# Auto-accept / 自动接受
|
|
311
|
+
peer = NetPeer(self, addr, request.connection_number)
|
|
312
|
+
self._peers[addr] = peer
|
|
313
|
+
await peer.accept_connection(request)
|
|
314
|
+
|
|
315
|
+
async def _handle_disconnect(self, peer: NetPeer, packet: NetPacket) -> None:
|
|
316
|
+
"""
|
|
317
|
+
Handle disconnect packet / 处理断开连接数据包。
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
peer: Peer that disconnected / 断开连接的对等端
|
|
321
|
+
packet: Disconnect packet / 断开连接数据包
|
|
322
|
+
"""
|
|
323
|
+
addr = peer.address
|
|
324
|
+
peer.shutdown()
|
|
325
|
+
|
|
326
|
+
if addr in self._peers:
|
|
327
|
+
del self._peers[addr]
|
|
328
|
+
|
|
329
|
+
if self._listener:
|
|
330
|
+
self._listener.on_peer_disconnect(peer, DisconnectReason.REMOTE_CONNECTION_CLOSE)
|
|
331
|
+
|
|
332
|
+
def _send_reject(self, addr: tuple) -> None:
|
|
333
|
+
"""Send connection reject / 发送连接拒绝"""
|
|
334
|
+
packet = NetPacket(PacketProperty.DISCONNECT, 8)
|
|
335
|
+
# Write reject reason / 写入拒绝原因
|
|
336
|
+
if self._socket:
|
|
337
|
+
self._socket.sendto(packet.get_bytes(), addr)
|
|
338
|
+
|
|
339
|
+
def _send_invalid_protocol(self, addr: tuple) -> None:
|
|
340
|
+
"""Send invalid protocol response / 发送无效协议响应"""
|
|
341
|
+
packet = NetPacket(PacketProperty.INVALID_PROTOCOL)
|
|
342
|
+
if self._socket:
|
|
343
|
+
self._socket.sendto(packet.get_bytes(), addr)
|
|
344
|
+
|
|
345
|
+
def get_packet_from_pool(self, size: int) -> NetPacket:
|
|
346
|
+
"""Get packet from pool / 从池中获取数据包"""
|
|
347
|
+
return self._packet_pool.get(size)
|
|
348
|
+
|
|
349
|
+
def recycle_packet(self, packet: NetPacket) -> None:
|
|
350
|
+
"""Recycle packet to pool / 将数据包回收至池中"""
|
|
351
|
+
self._packet_pool.recycle(packet)
|
|
352
|
+
|
|
353
|
+
def __del__(self):
|
|
354
|
+
"""Cleanup on destruction / 销毁时清理"""
|
|
355
|
+
self.stop()
|