easyprotolib 0.1.0__tar.gz

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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 baiYunMieAwa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,297 @@
1
+ Metadata-Version: 2.4
2
+ Name: easyprotolib
3
+ Version: 0.1.0
4
+ Summary: A Minecraft protocol library written in Python.
5
+ Author-email: baiYunMieAwa <baiyunmie@163.com>
6
+ License: MIT License
7
+ Project-URL: Homepage, https://github.com/baiYunMieAwa/EasyProtoLib
8
+ Project-URL: Bug Tracker, https://github.com/baiYunMieAwa/EasyProtoLib/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: mutf8>=1.0.0
16
+ Dynamic: license-file
17
+
18
+ EasyProtoLib
19
+ ============
20
+
21
+ ---
22
+
23
+ ## English
24
+
25
+ ### Description
26
+ This is a Minecraft protocol library written in `Python`, with lightweight and ease of use as its primary goals, and high performance **within pure Python** as a secondary goal. Currently, it only supports MCJE 1.18.2. Due to the author's academic commitments, this library is currently in a **semi-hibernation** state. Please use it with caution.
27
+
28
+ ### Quick Start
29
+
30
+ #### Installation
31
+
32
+ Install this protocol library using `pip`:
33
+ ```console
34
+ python -m pip install easyprotolib
35
+ ```
36
+
37
+ #### Build Your First Packet
38
+
39
+ > This protocol library does not provide a network layer abstraction; it is only responsible for protocol construction and parsing.
40
+
41
+ ```python
42
+ import easyprotolib as ep # Import EasyProtoLib
43
+
44
+ packet = ep.MCSHandshake(
45
+ ProtocolVersion=ep.MCVarInt(758), # Set protocol version (758 corresponds to 1.18.2)
46
+ ServerAddress=ep.MCString("127.0.0.1"), # Set server address (not normally validated by vanilla servers)
47
+ ServerPort=ep.MCUnsignedShort(25565), # Set server port
48
+ NextState=ep.MCVarInt(1) # Set next protocol state
49
+ )
50
+
51
+ data = packet.pack() # Serialize the packet, return serialized result
52
+ print(data)
53
+ # Can use socket.socket().send(data) to send the packet
54
+ ```
55
+
56
+ The field names of a packet can be found in the `fields` class attribute of the packet class. Each item in `fields` contains the field name as the first element, the field type as the second, and the default value as the third; if `None`, it means no default value. Field names are case‑insensitive and ignore spaces, underscores, and hyphens. Therefore, the following code is equivalent to the one above:
57
+
58
+ ```python
59
+ import easyprotolib as ep # Import EasyProtoLib
60
+
61
+ # A more Pythonic style
62
+ packet = ep.MCSHandshake(
63
+ protocol_version=ep.MCVarInt(758), # Set protocol version (758 corresponds to 1.18.2)
64
+ server_address=ep.MCString("127.0.0.1"), # Set server address (not normally validated by vanilla servers)
65
+ # Server port uses default MCUnsignedShort(25565)
66
+ next_state=ep.MCVarInt(1) # Set next protocol state
67
+ )
68
+
69
+ data = packet.pack() # Serialize the packet, return serialized result
70
+ print(data)
71
+ # Can use socket.socket().send(data) to send the packet
72
+ ```
73
+
74
+ #### Parse a Packet
75
+
76
+ ```python
77
+ import easyprotolib as ep
78
+
79
+ data = b'\x10\x00\xf6\x05\t127.0.0.1c\xdd\x01'
80
+ config = ep.MCConfig(ep.STATE_HANDSHAKE, ep.SIDE_SERVER) # Configure yourself; ep.SIDE_SERVER means you are the server side
81
+
82
+ packet = ep.MCDataPacket.unpack(config, data)
83
+
84
+ print(f"Packet ID: {packet.packet_id}") # Packet ID: 0
85
+ print(f"Packet class: {packet.__class__.__name__}") # Packet class: MCSHandshake
86
+ print(f"Packet data: {packet.data}") # Packet data: {'ProtocolVersion': 758, ...}
87
+ print(f"Packet length: {packet.length}") # Packet length: 17
88
+ print(f"Remaining data: {data[packet.length:]}") # Remaining data: b''
89
+ # You can repeatedly call MCDataPacket.deserialization() until it returns None, meaning the remaining data is not enough to form a complete packet.
90
+ ```
91
+
92
+ #### Custom Packet
93
+
94
+ ```python
95
+ import easyprotolib as ep
96
+
97
+ # Library naming convention: MC + receiving side (C/S) + packet name + (optional) State for disambiguation
98
+ class MCSMyDataPacket(ep.MCSPlayDataPacket): # A packet received and processed by the server (MCS) in the Play state
99
+ fields = [
100
+ # Field name: IntField; Field type: VarInt; Default: None
101
+ ("IntField", ep.MCVarInt, None),
102
+ # Field name: StringField; Field type: MCString; Default: ep.MCString("Hello world")
103
+ ("StringField", ep.MCString, ep.MCString("Hello world"))
104
+ ]
105
+ packet_id = 0xFF # Packet ID: 0xff
106
+
107
+ # You can then construct or parse this packet just like a native packet, without any additional handling.
108
+ ```
109
+
110
+ #### Custom Data Types
111
+
112
+ **Custom Atomic Data Type**
113
+ ```python
114
+ import easyprotolib as ep
115
+
116
+ class MCMyObject(ep.MCObject):
117
+ def __init__(self, data: tuple[str, int]):
118
+ super().__init__(data) # Automatically registers self.data
119
+
120
+ def _obj_serialization(self) -> bytearray:
121
+ # Implement serialization; do not override serialization()
122
+ return ep.MCString(self.data[0]) + ep.MCVarInt(self.data[1]) # No need to explicitly call MCObject's serialization; addition automatically serializes
123
+
124
+ @staticmethod
125
+ def _obj_deserialization(data: bytearray) -> tuple[tuple[str, int], int]:
126
+ # Implement deserialization (static)
127
+ string, offset = ep.MCString.deserialization(data)
128
+ varint, offset2 = ep.MCVarInt.deserialization(data[offset:])
129
+ # Return value: tuple[actual payload, number of bytes processed]
130
+ return (string, varint), offset + offset2
131
+
132
+ # You can then use this data type normally.
133
+ ```
134
+
135
+ **Custom Array Type**
136
+ ```python
137
+ import easyprotolib as ep
138
+
139
+ class MCIntArray(ep.MCObjectArray): # Defines a 1D array of MCInt
140
+ MCObjectType = ep.MCInt # Specify the element type
141
+
142
+ # You can then use this array normally.
143
+
144
+ class MCIntArrayArray(ep.MCObjectArray): # Defines a 2D array of MCInt
145
+ MCObjectType = MCIntArray # Specify the corresponding 1D array type; similarly for higher dimensions
146
+
147
+ # You can then use this array normally.
148
+ ```
149
+
150
+ ### Third‑Party Library Copyright Information
151
+ | Name | Version | License |
152
+ |--------|----------|---------|
153
+ | mutf8 | >=1.0.0 | MIT |
154
+
155
+ For full details, see `THIRD-PARTY.json`.
156
+
157
+ ### Disclaimer
158
+ The authors and contributors of this library are not responsible for any consequences arising from the use of this library. The authors and contributors firmly oppose any illegal activities carried out based on this project, such as attacking servers.
159
+
160
+ ---
161
+
162
+ ## 中文
163
+
164
+ ### 描述
165
+ 这是一个使用 `Python` 编写的 Minecraft 协议库,以轻量、易用为主要目标,以**在纯Python范围内**的高性能为次要目标,目前仅支持MCJE 1.18.2。由于作者学业问题,本库目前处于**半停更**状态。请谨慎使用本库。
166
+
167
+ ### 快速开始
168
+
169
+ #### 安装
170
+
171
+ 使用 `pip` 安装此协议库:
172
+ ```console
173
+ python -m pip install easyprotolib
174
+ ```
175
+
176
+ #### 构建你的第一个数据包
177
+
178
+ > 此协议库没有提供网络层抽象,仅负责协议构建和解析。
179
+
180
+ ```python
181
+ import easyprotolib as ep # 导入 EasyProtoLib
182
+
183
+ packet = ep.MCSHandshake(
184
+ ProtocolVersion=ep.MCVarInt(758), # 设置协议号(758对应1.18.2)
185
+ ServerAddress=ep.MCString("127.0.0.1"), # 设置服务器地址(通常不被原版服务器用于验证)
186
+ ServerPort=ep.MCUnsignedShort(25565), # 设置服务器端口
187
+ NextState=ep.MCVarInt(1) # 设置下一个协议状态
188
+ )
189
+
190
+ data = packet.pack() # 序列化数据包,返回序列化结果
191
+ print(data)
192
+ # 可使用 socket.socket().send(data) 发送数据包
193
+ ```
194
+
195
+ 数据包的字段名可以在数据包类中的 `fields` 类属性中找到。`fields` 每一项的第一项是字段名,第二项是字段类型,第三项是默认值,如为 `None` 则代表无默认值。字段名忽略大小写,忽略空格、下划线和连字符。所以以下代码和以上代码等价:
196
+
197
+ ```python
198
+ import easyprotolib as ep # 导入 EasyProtoLib
199
+
200
+ # 更符合Python编码习惯的写法
201
+ packet = ep.MCSHandshake(
202
+ protocol_version=ep.MCVarInt(758), # 设置协议号(758对应1.18.2)
203
+ server_address=ep.MCString("127.0.0.1"), # 设置服务器地址(通常不被原版服务器用于验证)
204
+ # 服务器端口使用默认值 MCUnsignedShort(25565)
205
+ next_state=ep.MCVarInt(1) # 设置下一个协议状态
206
+ )
207
+
208
+ data = packet.pack() # 序列化数据包,返回序列化结果
209
+ print(data)
210
+ # 可使用 socket.socket().send(data) 发送数据包
211
+ ```
212
+
213
+ #### 解析数据包
214
+
215
+ ```python
216
+ import easyprotolib as ep
217
+
218
+ data = b'\x10\x00\xf6\x05\t127.0.0.1c\xdd\x01'
219
+ config = ep.MCConfig(ep.STATE_HANDSHAKE, ep.SIDE_SERVER) # 配置自己, ep.SIDE_SERVER 表示自己是服务端
220
+
221
+ packet = ep.MCDataPacket.unpack(config, data)
222
+
223
+ print(f"数据包ID: {packet.packet_id}") # 数据包ID: 0
224
+ print(f"数据包类: {packet.__class__.__name__}") # 数据包类: MCSHandshake
225
+ print(f"数据包数据: {packet.data}") # 数据包数据: {'ProtocolVersion': 758, ...}
226
+ print(f"数据包长度: {packet.length}") # 数据包长度: 17
227
+ print(f"下一段数据: {data[packet.length:]}") # 下一段数据: b''
228
+ # 可以循环调用MCDataPacket.deserialization(), 直到返回值为None, 则意味着剩余数据凑不出一个完整的数据包
229
+ ```
230
+
231
+ #### 自定义数据包
232
+
233
+ ```python
234
+ import easyprotolib as ep
235
+
236
+ # 库命名约定: MC + 接收端(C/S) + 包名 + 所处的State(可选, 用于消歧义)
237
+ class MCSMyDataPacket(ep.MCSPlayDataPacket): # 由服务端(MCS)在Play状态下接收并处理的数据包
238
+ fields = [
239
+ # 字段名: IntField; 字段类型: VarInt; 默认值: 无
240
+ ("IntField", ep.MCVarInt, None),
241
+ # 字段名: StringField; 字段类型: MCString; 默认值: ep.MCString("Hello world")
242
+ ("StringField", ep.MCString, ep.MCString("Hello world"))
243
+ ]
244
+ packet_id = 0xFF # 数据包ID: 0xff
245
+
246
+ # 随后可像原生数据包般构建或解析该数据包, 无需其他处理
247
+ ```
248
+
249
+ #### 自定义数据类型
250
+
251
+ **自定义原子数据类型**
252
+ ```python
253
+ import easyprotolib as ep
254
+
255
+ class MCMyObject(ep.MCObject):
256
+ def __init__(self, data: tuple[str, int]):
257
+ super().__init__(data) # 自动注册 self.data
258
+
259
+ def _obj_serialization(self) -> bytearray:
260
+ # 编写序列化方法, 请不要重写 serialization() 方法
261
+ return ep.MCString(self.data[0]) + ep.MCVarInt(self.data[1]) # 无需显式调用 MCObject 的序列化方法, 相加时会自动序列化
262
+
263
+ @staticmethod
264
+ def _obj_deserialization(data: bytearray) -> tuple[tuple[str, int], int]:
265
+ # 编写反序列化方法(静态)
266
+ string, offset = ep.MCString.deserialization(data)
267
+ varint, offset2 = ep.MCVarInt.deserialization(data[offset:])
268
+ # 返回值: tuple[实际负载, 已处理的字节流长度]
269
+ return (string, varint), offset + offset2
270
+
271
+ # 随后可正常使用该数据类型
272
+ ```
273
+
274
+ **自定义数组类型**
275
+ ```python
276
+ import easyprotolib as ep
277
+
278
+ class MCIntArray(ep.MCObjectArray): # 定义一维 MCInt 数组
279
+ MCObjectType = ep.MCInt # 写上该数组的元素类型
280
+
281
+ # 随后可正常使用该数组
282
+
283
+ class MCIntArrayArray(ep.MCObjectArray): # 定义二维 MCInt 数组
284
+ MCObjectType = MCIntArray # 写上对应的一维数组的类型即可, 多维数组以此类推
285
+
286
+ # 随后可正常使用该数组
287
+ ```
288
+
289
+ ### 第三方库版权信息
290
+ | 名称 | 版本 | 协议 |
291
+ |-------|---------|-----|
292
+ | mutf8 | >=1.0.0 | MIT |
293
+
294
+ 完整信息参见 `THIRD-PARTY.json` 。
295
+
296
+ ### 免责声明
297
+ 本库的作者和贡献者不对因使用本库而产生的任何后果负责。作者和贡献者坚决反对任何基于本项目实施的非法活动,例如攻击服务器。
@@ -0,0 +1,280 @@
1
+ EasyProtoLib
2
+ ============
3
+
4
+ ---
5
+
6
+ ## English
7
+
8
+ ### Description
9
+ This is a Minecraft protocol library written in `Python`, with lightweight and ease of use as its primary goals, and high performance **within pure Python** as a secondary goal. Currently, it only supports MCJE 1.18.2. Due to the author's academic commitments, this library is currently in a **semi-hibernation** state. Please use it with caution.
10
+
11
+ ### Quick Start
12
+
13
+ #### Installation
14
+
15
+ Install this protocol library using `pip`:
16
+ ```console
17
+ python -m pip install easyprotolib
18
+ ```
19
+
20
+ #### Build Your First Packet
21
+
22
+ > This protocol library does not provide a network layer abstraction; it is only responsible for protocol construction and parsing.
23
+
24
+ ```python
25
+ import easyprotolib as ep # Import EasyProtoLib
26
+
27
+ packet = ep.MCSHandshake(
28
+ ProtocolVersion=ep.MCVarInt(758), # Set protocol version (758 corresponds to 1.18.2)
29
+ ServerAddress=ep.MCString("127.0.0.1"), # Set server address (not normally validated by vanilla servers)
30
+ ServerPort=ep.MCUnsignedShort(25565), # Set server port
31
+ NextState=ep.MCVarInt(1) # Set next protocol state
32
+ )
33
+
34
+ data = packet.pack() # Serialize the packet, return serialized result
35
+ print(data)
36
+ # Can use socket.socket().send(data) to send the packet
37
+ ```
38
+
39
+ The field names of a packet can be found in the `fields` class attribute of the packet class. Each item in `fields` contains the field name as the first element, the field type as the second, and the default value as the third; if `None`, it means no default value. Field names are case‑insensitive and ignore spaces, underscores, and hyphens. Therefore, the following code is equivalent to the one above:
40
+
41
+ ```python
42
+ import easyprotolib as ep # Import EasyProtoLib
43
+
44
+ # A more Pythonic style
45
+ packet = ep.MCSHandshake(
46
+ protocol_version=ep.MCVarInt(758), # Set protocol version (758 corresponds to 1.18.2)
47
+ server_address=ep.MCString("127.0.0.1"), # Set server address (not normally validated by vanilla servers)
48
+ # Server port uses default MCUnsignedShort(25565)
49
+ next_state=ep.MCVarInt(1) # Set next protocol state
50
+ )
51
+
52
+ data = packet.pack() # Serialize the packet, return serialized result
53
+ print(data)
54
+ # Can use socket.socket().send(data) to send the packet
55
+ ```
56
+
57
+ #### Parse a Packet
58
+
59
+ ```python
60
+ import easyprotolib as ep
61
+
62
+ data = b'\x10\x00\xf6\x05\t127.0.0.1c\xdd\x01'
63
+ config = ep.MCConfig(ep.STATE_HANDSHAKE, ep.SIDE_SERVER) # Configure yourself; ep.SIDE_SERVER means you are the server side
64
+
65
+ packet = ep.MCDataPacket.unpack(config, data)
66
+
67
+ print(f"Packet ID: {packet.packet_id}") # Packet ID: 0
68
+ print(f"Packet class: {packet.__class__.__name__}") # Packet class: MCSHandshake
69
+ print(f"Packet data: {packet.data}") # Packet data: {'ProtocolVersion': 758, ...}
70
+ print(f"Packet length: {packet.length}") # Packet length: 17
71
+ print(f"Remaining data: {data[packet.length:]}") # Remaining data: b''
72
+ # You can repeatedly call MCDataPacket.deserialization() until it returns None, meaning the remaining data is not enough to form a complete packet.
73
+ ```
74
+
75
+ #### Custom Packet
76
+
77
+ ```python
78
+ import easyprotolib as ep
79
+
80
+ # Library naming convention: MC + receiving side (C/S) + packet name + (optional) State for disambiguation
81
+ class MCSMyDataPacket(ep.MCSPlayDataPacket): # A packet received and processed by the server (MCS) in the Play state
82
+ fields = [
83
+ # Field name: IntField; Field type: VarInt; Default: None
84
+ ("IntField", ep.MCVarInt, None),
85
+ # Field name: StringField; Field type: MCString; Default: ep.MCString("Hello world")
86
+ ("StringField", ep.MCString, ep.MCString("Hello world"))
87
+ ]
88
+ packet_id = 0xFF # Packet ID: 0xff
89
+
90
+ # You can then construct or parse this packet just like a native packet, without any additional handling.
91
+ ```
92
+
93
+ #### Custom Data Types
94
+
95
+ **Custom Atomic Data Type**
96
+ ```python
97
+ import easyprotolib as ep
98
+
99
+ class MCMyObject(ep.MCObject):
100
+ def __init__(self, data: tuple[str, int]):
101
+ super().__init__(data) # Automatically registers self.data
102
+
103
+ def _obj_serialization(self) -> bytearray:
104
+ # Implement serialization; do not override serialization()
105
+ return ep.MCString(self.data[0]) + ep.MCVarInt(self.data[1]) # No need to explicitly call MCObject's serialization; addition automatically serializes
106
+
107
+ @staticmethod
108
+ def _obj_deserialization(data: bytearray) -> tuple[tuple[str, int], int]:
109
+ # Implement deserialization (static)
110
+ string, offset = ep.MCString.deserialization(data)
111
+ varint, offset2 = ep.MCVarInt.deserialization(data[offset:])
112
+ # Return value: tuple[actual payload, number of bytes processed]
113
+ return (string, varint), offset + offset2
114
+
115
+ # You can then use this data type normally.
116
+ ```
117
+
118
+ **Custom Array Type**
119
+ ```python
120
+ import easyprotolib as ep
121
+
122
+ class MCIntArray(ep.MCObjectArray): # Defines a 1D array of MCInt
123
+ MCObjectType = ep.MCInt # Specify the element type
124
+
125
+ # You can then use this array normally.
126
+
127
+ class MCIntArrayArray(ep.MCObjectArray): # Defines a 2D array of MCInt
128
+ MCObjectType = MCIntArray # Specify the corresponding 1D array type; similarly for higher dimensions
129
+
130
+ # You can then use this array normally.
131
+ ```
132
+
133
+ ### Third‑Party Library Copyright Information
134
+ | Name | Version | License |
135
+ |--------|----------|---------|
136
+ | mutf8 | >=1.0.0 | MIT |
137
+
138
+ For full details, see `THIRD-PARTY.json`.
139
+
140
+ ### Disclaimer
141
+ The authors and contributors of this library are not responsible for any consequences arising from the use of this library. The authors and contributors firmly oppose any illegal activities carried out based on this project, such as attacking servers.
142
+
143
+ ---
144
+
145
+ ## 中文
146
+
147
+ ### 描述
148
+ 这是一个使用 `Python` 编写的 Minecraft 协议库,以轻量、易用为主要目标,以**在纯Python范围内**的高性能为次要目标,目前仅支持MCJE 1.18.2。由于作者学业问题,本库目前处于**半停更**状态。请谨慎使用本库。
149
+
150
+ ### 快速开始
151
+
152
+ #### 安装
153
+
154
+ 使用 `pip` 安装此协议库:
155
+ ```console
156
+ python -m pip install easyprotolib
157
+ ```
158
+
159
+ #### 构建你的第一个数据包
160
+
161
+ > 此协议库没有提供网络层抽象,仅负责协议构建和解析。
162
+
163
+ ```python
164
+ import easyprotolib as ep # 导入 EasyProtoLib
165
+
166
+ packet = ep.MCSHandshake(
167
+ ProtocolVersion=ep.MCVarInt(758), # 设置协议号(758对应1.18.2)
168
+ ServerAddress=ep.MCString("127.0.0.1"), # 设置服务器地址(通常不被原版服务器用于验证)
169
+ ServerPort=ep.MCUnsignedShort(25565), # 设置服务器端口
170
+ NextState=ep.MCVarInt(1) # 设置下一个协议状态
171
+ )
172
+
173
+ data = packet.pack() # 序列化数据包,返回序列化结果
174
+ print(data)
175
+ # 可使用 socket.socket().send(data) 发送数据包
176
+ ```
177
+
178
+ 数据包的字段名可以在数据包类中的 `fields` 类属性中找到。`fields` 每一项的第一项是字段名,第二项是字段类型,第三项是默认值,如为 `None` 则代表无默认值。字段名忽略大小写,忽略空格、下划线和连字符。所以以下代码和以上代码等价:
179
+
180
+ ```python
181
+ import easyprotolib as ep # 导入 EasyProtoLib
182
+
183
+ # 更符合Python编码习惯的写法
184
+ packet = ep.MCSHandshake(
185
+ protocol_version=ep.MCVarInt(758), # 设置协议号(758对应1.18.2)
186
+ server_address=ep.MCString("127.0.0.1"), # 设置服务器地址(通常不被原版服务器用于验证)
187
+ # 服务器端口使用默认值 MCUnsignedShort(25565)
188
+ next_state=ep.MCVarInt(1) # 设置下一个协议状态
189
+ )
190
+
191
+ data = packet.pack() # 序列化数据包,返回序列化结果
192
+ print(data)
193
+ # 可使用 socket.socket().send(data) 发送数据包
194
+ ```
195
+
196
+ #### 解析数据包
197
+
198
+ ```python
199
+ import easyprotolib as ep
200
+
201
+ data = b'\x10\x00\xf6\x05\t127.0.0.1c\xdd\x01'
202
+ config = ep.MCConfig(ep.STATE_HANDSHAKE, ep.SIDE_SERVER) # 配置自己, ep.SIDE_SERVER 表示自己是服务端
203
+
204
+ packet = ep.MCDataPacket.unpack(config, data)
205
+
206
+ print(f"数据包ID: {packet.packet_id}") # 数据包ID: 0
207
+ print(f"数据包类: {packet.__class__.__name__}") # 数据包类: MCSHandshake
208
+ print(f"数据包数据: {packet.data}") # 数据包数据: {'ProtocolVersion': 758, ...}
209
+ print(f"数据包长度: {packet.length}") # 数据包长度: 17
210
+ print(f"下一段数据: {data[packet.length:]}") # 下一段数据: b''
211
+ # 可以循环调用MCDataPacket.deserialization(), 直到返回值为None, 则意味着剩余数据凑不出一个完整的数据包
212
+ ```
213
+
214
+ #### 自定义数据包
215
+
216
+ ```python
217
+ import easyprotolib as ep
218
+
219
+ # 库命名约定: MC + 接收端(C/S) + 包名 + 所处的State(可选, 用于消歧义)
220
+ class MCSMyDataPacket(ep.MCSPlayDataPacket): # 由服务端(MCS)在Play状态下接收并处理的数据包
221
+ fields = [
222
+ # 字段名: IntField; 字段类型: VarInt; 默认值: 无
223
+ ("IntField", ep.MCVarInt, None),
224
+ # 字段名: StringField; 字段类型: MCString; 默认值: ep.MCString("Hello world")
225
+ ("StringField", ep.MCString, ep.MCString("Hello world"))
226
+ ]
227
+ packet_id = 0xFF # 数据包ID: 0xff
228
+
229
+ # 随后可像原生数据包般构建或解析该数据包, 无需其他处理
230
+ ```
231
+
232
+ #### 自定义数据类型
233
+
234
+ **自定义原子数据类型**
235
+ ```python
236
+ import easyprotolib as ep
237
+
238
+ class MCMyObject(ep.MCObject):
239
+ def __init__(self, data: tuple[str, int]):
240
+ super().__init__(data) # 自动注册 self.data
241
+
242
+ def _obj_serialization(self) -> bytearray:
243
+ # 编写序列化方法, 请不要重写 serialization() 方法
244
+ return ep.MCString(self.data[0]) + ep.MCVarInt(self.data[1]) # 无需显式调用 MCObject 的序列化方法, 相加时会自动序列化
245
+
246
+ @staticmethod
247
+ def _obj_deserialization(data: bytearray) -> tuple[tuple[str, int], int]:
248
+ # 编写反序列化方法(静态)
249
+ string, offset = ep.MCString.deserialization(data)
250
+ varint, offset2 = ep.MCVarInt.deserialization(data[offset:])
251
+ # 返回值: tuple[实际负载, 已处理的字节流长度]
252
+ return (string, varint), offset + offset2
253
+
254
+ # 随后可正常使用该数据类型
255
+ ```
256
+
257
+ **自定义数组类型**
258
+ ```python
259
+ import easyprotolib as ep
260
+
261
+ class MCIntArray(ep.MCObjectArray): # 定义一维 MCInt 数组
262
+ MCObjectType = ep.MCInt # 写上该数组的元素类型
263
+
264
+ # 随后可正常使用该数组
265
+
266
+ class MCIntArrayArray(ep.MCObjectArray): # 定义二维 MCInt 数组
267
+ MCObjectType = MCIntArray # 写上对应的一维数组的类型即可, 多维数组以此类推
268
+
269
+ # 随后可正常使用该数组
270
+ ```
271
+
272
+ ### 第三方库版权信息
273
+ | 名称 | 版本 | 协议 |
274
+ |-------|---------|-----|
275
+ | mutf8 | >=1.0.0 | MIT |
276
+
277
+ 完整信息参见 `THIRD-PARTY.json` 。
278
+
279
+ ### 免责声明
280
+ 本库的作者和贡献者不对因使用本库而产生的任何后果负责。作者和贡献者坚决反对任何基于本项目实施的非法活动,例如攻击服务器。
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"] # 构建所需的工具
3
+ build-backend = "setuptools.build_meta" # 使用的构建后端
4
+
5
+ [project]
6
+ name = "easyprotolib" # 用户用 pip install 的名字,需唯一
7
+ version = "0.1.0" # 遵循语义化版本规范
8
+ authors = [
9
+ { name = "baiYunMieAwa", email = "baiyunmie@163.com" },
10
+ ]
11
+ description = "A Minecraft protocol library written in Python."
12
+ readme = "README.md" # 项目说明文件
13
+ requires-python = ">=3.10" # 支持的Python版本
14
+ license = { text = "MIT License" } # 开源许可证
15
+ classifiers = [ # PyPI 分类标签
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ ]
20
+ dependencies = [ # 项目依赖
21
+ "mutf8>=1.0.0",
22
+ ]
23
+
24
+ [project.urls]
25
+ "Homepage" = "https://github.com/baiYunMieAwa/EasyProtoLib"
26
+ "Bug Tracker" = "https://github.com/baiYunMieAwa/EasyProtoLib/issues"
27
+
28
+ [tool.setuptools.packages.find]
29
+ where = ["src"] # 告诉 setuptools 去 src 目录下找包
30
+
31
+ # [tool.setuptools]
32
+ # ext-modules = [
33
+ # {name = "pack", sources = ["src/easyprotolib/_pack.pyx"]},
34
+ # ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+