2023-03-16 13:49:55 +00:00
|
|
|
A teeworlds network protocol library, designed according to sans I/O (http://sans-io.readthedocs.io/) principles
|
2023-03-12 21:12:07 +00:00
|
|
|
|
2023-03-19 10:44:40 +00:00
|
|
|
# THIS LIBRARY IS IN EARLY DEVELOPMENT
|
|
|
|
|
2023-03-31 08:17:44 +00:00
|
|
|
## Do not get bamboozled by the mature looking readme!
|
|
|
|
## This project is not in a very usable state yet. It is in very early development!
|
|
|
|
## APIs might change and many essential features are missing!
|
|
|
|
|
|
|
|
---
|
2023-03-19 10:44:40 +00:00
|
|
|
|
2023-03-16 15:56:37 +00:00
|
|
|
## install
|
|
|
|
|
|
|
|
```bash
|
|
|
|
pip install twnet_parser
|
|
|
|
```
|
|
|
|
|
2023-03-16 09:26:36 +00:00
|
|
|
## sample usage
|
2023-03-12 21:12:07 +00:00
|
|
|
|
|
|
|
```python
|
2023-03-16 15:56:37 +00:00
|
|
|
import twnet_parser.packet
|
2023-03-18 09:03:42 +00:00
|
|
|
packet = twnet_parser.packet.parse7(b'\x04\x0a\x00\xcf\x2e\xde\x1d\04') # 0.7 close
|
2023-03-16 11:08:02 +00:00
|
|
|
|
|
|
|
print(packet) # => <class: 'TwPacket'>: {'version': '0.7', 'header': <class: 'Header'>, 'messages': [<class: 'CtrlMessage'>]}
|
|
|
|
print(packet.header) # => <class: 'Header'>: {'flags': <class: 'PacketFlags7, 'size': 0, 'ack': 10, 'token': b'\xcf.\xde\x1d', 'num_chunks': 0}
|
|
|
|
print(packet.header.flags) # => <class: 'PacketFlags7'>: {'control': True, 'resend': False, 'compression': False, 'connless': False}
|
|
|
|
for msg in packet.messages:
|
2023-03-25 13:22:45 +00:00
|
|
|
print(msg.message_name) # => close
|
2023-03-12 21:12:07 +00:00
|
|
|
```
|
2023-03-14 21:58:06 +00:00
|
|
|
|
2023-11-14 14:05:20 +00:00
|
|
|
More examples can be found in the [examples/](./examples/) folder:
|
2024-02-23 04:48:12 +00:00
|
|
|
### 0.7
|
|
|
|
|
2023-11-14 14:05:20 +00:00
|
|
|
- [map downloader client](./examples/07/download_map/)
|
|
|
|
- [flood client (connect multiple tees to a server)](./examples/07/flood/)
|
2024-02-23 04:48:12 +00:00
|
|
|
|
|
|
|
### 0.6 and 0.7
|
|
|
|
|
|
|
|
- [pcap printer (capture with tcpdump and print teeworlds traffic details)](./examples/06_and_07/print_pcap_files/)
|
2023-11-14 14:01:57 +00:00
|
|
|
|
2023-03-18 08:35:43 +00:00
|
|
|
## Features
|
|
|
|
|
2024-02-26 03:36:03 +00:00
|
|
|
| Feature | 0.6.4 | 0.6.5 | 0.7.0 - 0.7.5 |
|
|
|
|
| ---------------------------- | ------------------ | ------------------ | ------------------ |
|
|
|
|
| Deserialize packet headers | | :heavy_check_mark: | :heavy_check_mark: |
|
|
|
|
| Deserialize chunk headers | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
|
|
| Deserialize messages | 90% | 90% | 90% |
|
|
|
|
| Deserialize snapshots | | | |
|
|
|
|
| Deserialize connless packets | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
|
|
| Serialize packet headers | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
|
|
| Serialize chunk headers | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
|
|
| Serialize messages | 90% | 90% | 90% |
|
|
|
|
| Serialize snapshots | | | |
|
|
|
|
| Serialize connless packets | | :heavy_check_mark: | :heavy_check_mark: |
|
2023-03-18 08:35:43 +00:00
|
|
|
|
|
|
|
## Non-Features (also not planned for this library)
|
|
|
|
|
|
|
|
| Feature | Status | Where to find it |
|
|
|
|
| ------------------------------ | ------- | ------------------------------------------- |
|
|
|
|
| Networking | :x: | TODO: link if someone implemented it on top |
|
|
|
|
| Protocol version detection | :x: | TODO: link if someone implemented it on top |
|
2023-04-07 10:54:18 +00:00
|
|
|
| Track sequence number state | :x: | TODO: link if someone implemented it on top |
|
|
|
|
| Track connection state | :x: | TODO: link if someone implemented it on top |
|
2023-03-18 08:35:43 +00:00
|
|
|
|
|
|
|
Look elsewhere for these features. Or use this library to implement them on top.
|
|
|
|
|
2023-04-07 10:54:18 +00:00
|
|
|
This project is intentionally only covering parsing the protocol.
|
|
|
|
Not fully implemeting a state machine of the protocol.
|
|
|
|
Or a fully working client / server software.
|
|
|
|
|
|
|
|
If you want to build something with this library
|
|
|
|
you do have to understand how the protocol works
|
|
|
|
and when the client and server have to send what.
|
|
|
|
|
|
|
|
This [protocol documentation](https://chillerdragon.github.io/teeworlds-protocol/index.html)
|
|
|
|
should get you started to understand the basics.
|
|
|
|
|
2023-04-29 07:25:47 +00:00
|
|
|
## Convenient defaults and fully customizable
|
|
|
|
|
|
|
|
```python
|
2023-04-29 07:31:35 +00:00
|
|
|
from twnet_parser.packet import TwPacket
|
|
|
|
from twnet_parser.messages7.game.cl_call_vote import MsgClCallVote
|
|
|
|
|
2023-04-29 07:25:47 +00:00
|
|
|
"""
|
|
|
|
The call to packet.pack() generates
|
|
|
|
a valid byte array that can be sent as an udp payload
|
|
|
|
|
|
|
|
It uses default values for things like:
|
|
|
|
security token, acknowledge number, packet flags,
|
|
|
|
chunk header (flags, size, seq),
|
|
|
|
vote type, vote value, vote reason, vote force
|
|
|
|
|
|
|
|
It computes a valid chunk header size field based
|
|
|
|
on the payload length.
|
|
|
|
|
|
|
|
It sets the correct num chunks field in the packet header
|
|
|
|
based on the amount of messages you added (1 in this case)
|
|
|
|
|
|
|
|
While this has all fields set that packet would be dropped by a vanilla
|
|
|
|
implementation because the security token and sequence number is wrong.
|
|
|
|
So you have to take care of those your self.
|
|
|
|
"""
|
|
|
|
packet = TwPacket()
|
|
|
|
msg = MsgClCallVote()
|
|
|
|
packet.messages.append(msg)
|
2023-04-29 07:31:35 +00:00
|
|
|
packet.pack() # => b'\x00\x00\x01\xff\xff\xff\xff\x00\x00\x80\x01default\x00default\x00default\x00\x00'
|
2023-04-29 07:25:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
Here we also send a Call vote message.
|
|
|
|
But this time we set a security token and a few other fields.
|
|
|
|
|
|
|
|
Note that we set num_chunks to 6 which is wrong because
|
|
|
|
we only send one message (MsgClCallVote).
|
|
|
|
But this library allows you to do so.
|
|
|
|
And it will not compute the correct amount.
|
|
|
|
But use your explicitly set wrong one instead.
|
|
|
|
|
|
|
|
This allows you to have full control and craft any kind of packet.
|
|
|
|
May it be correct or not.
|
|
|
|
"""
|
|
|
|
packet = TwPacket()
|
|
|
|
packet.header.token = b'\x48\x1f\x93\xd7'
|
|
|
|
packet.header.num_chunks = 6
|
|
|
|
packet.header.ack = 638
|
|
|
|
packet.header.flags.control = False
|
|
|
|
packet.header.flags.compression = False
|
|
|
|
msg = MsgClCallVote()
|
|
|
|
msg.header.seq = 10
|
|
|
|
msg.type = 'option'
|
|
|
|
msg.value = 'test'
|
|
|
|
msg.reason = ''
|
|
|
|
msg.force = False
|
|
|
|
packet.messages.append(msg)
|
2023-04-29 07:31:35 +00:00
|
|
|
packet.pack() # => b'\x02~\x06H\x1f\x93\xd7\x00\x00\x80\x01option\x00test\x00\x00\x00'
|
2023-04-29 07:25:47 +00:00
|
|
|
```
|
|
|
|
|
2023-06-18 10:51:07 +00:00
|
|
|
## Zero dependencies by default
|
|
|
|
|
|
|
|
Running ``pip install twnet_parser`` will not install any additional packages.
|
|
|
|
|
|
|
|
But there is an optional dependency for huffman compression.
|
|
|
|
By default twnet_parser is using the huffman compression code from the [TeeAI](https://github.com/edg-l/TeeAI)
|
|
|
|
project which is written in pure python.
|
|
|
|
If you have [libtw2-huffman](https://pypi.org/project/libtw2-huffman/) installed it will use that one instead.
|
|
|
|
Because it is faster since it is written in rust and has better error handling.
|
|
|
|
But since it is so much overhead it is not installed by default to keep twnet_parser light weight.
|
|
|
|
|
|
|
|
|
|
|
|
You can install it by running ``pip install libtw2-huffman``
|
|
|
|
or by running ``pip install -r requirements/optional.txt``
|
|
|
|
|
|
|
|
|
|
|
|
You can also check which huffman backend is currently active with these lines of code
|
|
|
|
|
|
|
|
```python
|
|
|
|
import twnet_parser.huffman
|
|
|
|
print(twnet_parser.huffman.backend_name()) # => rust-libtw2 or python-TeeAI
|
|
|
|
```
|
|
|
|
|
2023-03-16 14:04:01 +00:00
|
|
|
## development setup
|
2023-03-14 21:58:06 +00:00
|
|
|
|
|
|
|
```bash
|
|
|
|
git clone https://gitlab.com/teeworlds-network/twnet_parser
|
|
|
|
cd twnet_parser
|
|
|
|
python -m venv venv
|
|
|
|
source venv/bin/activate
|
2023-03-16 16:08:27 +00:00
|
|
|
pip install -r requirements/dev.txt
|
2023-06-04 09:52:38 +00:00
|
|
|
pre-commit install --hook-type commit-msg
|
2023-03-14 21:58:06 +00:00
|
|
|
```
|
2023-03-16 13:04:48 +00:00
|
|
|
|
|
|
|
## tests and linting
|
|
|
|
|
|
|
|
```bash
|
2023-03-16 13:49:55 +00:00
|
|
|
# dev dependencies
|
|
|
|
pip install -r requirements/dev.txt
|
|
|
|
|
2023-03-16 13:04:48 +00:00
|
|
|
# run unit tests
|
|
|
|
pytest .
|
|
|
|
|
|
|
|
# run style linter
|
|
|
|
pylint src/
|
|
|
|
|
|
|
|
# run type checker
|
|
|
|
mypy src/
|
2023-04-07 08:38:04 +00:00
|
|
|
|
|
|
|
# or use the bundle script that runs all tests
|
|
|
|
./scripts/run_tests.sh
|
2023-03-16 13:04:48 +00:00
|
|
|
```
|
|
|
|
|
2023-03-16 13:49:55 +00:00
|
|
|
## package and release
|
|
|
|
|
|
|
|
```bash
|
2023-03-16 15:43:53 +00:00
|
|
|
# manual
|
2023-03-16 13:49:55 +00:00
|
|
|
pip install -r requirements/dev.txt
|
2023-03-16 15:43:53 +00:00
|
|
|
version=0.0.2
|
2023-04-07 07:40:32 +00:00
|
|
|
sed -i "s/^version =.*/version = $version/" setup.cfg
|
2023-03-16 13:49:55 +00:00
|
|
|
python -m build
|
2023-03-16 15:43:53 +00:00
|
|
|
git tag -a "v$version" -m "# version $version"
|
2023-03-16 13:49:55 +00:00
|
|
|
python -m twine upload dist/*
|
2023-03-16 15:43:53 +00:00
|
|
|
|
|
|
|
# or use the interactive convience script
|
|
|
|
./scripts/release.sh
|
2023-03-16 13:49:55 +00:00
|
|
|
```
|