diff --git a/examples/download_map/download_map.py b/examples/download_map/download_map.py index 9f0a622..2c34df3 100755 --- a/examples/download_map/download_map.py +++ b/examples/download_map/download_map.py @@ -1,14 +1,27 @@ #!/usr/bin/env python -import socket +import socket, os + +from typing import Optional from twnet_parser.packet import TwPacket, parse7 from twnet_parser.messages7.control.token import CtrlToken from twnet_parser.messages7.control.connect import CtrlConnect from twnet_parser.messages7.system.info import MsgInfo +from twnet_parser.messages7.system.map_change import MsgMapChange +from twnet_parser.messages7.system.request_map_data import MsgRequestMapData -# TODO: import twnet_parser.constants.NET_MAX_PACKETSIZE -NET_MAX_PACKETSIZE = 1400 +from twnet_parser.constants import NET_MAX_PACKETSIZE, NET_MAX_SEQUENCE + +def progress(have, want): + if os.name == 'nt': + os.system('cls') + else: + os.system('clear') + percent = int(100 * have / want) + bar = '=' * int(percent / 2) + bar = bar[0:-1] + '>' + print(f"[{bar:50}] {have}/{want} {percent}%") host = 'localhost' port = 8303 @@ -17,18 +30,30 @@ dest_srv = (host, port) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(('', 0)) +downloaded_chunks = 0 +downloaded_bytes = 0 +sent_vital = 0 +got_vital = 0 +got_seqs = set() +map_info: Optional[MsgMapChange] = None my_token = b'\xff\xaa\xbb\xee' srv_token = b'\xff\xff\xff\xff' def send_msg(messages): global srv_token + global got_vital + global sent_vital if not isinstance(messages, list): messages = [messages] packet = TwPacket() packet.header.token = srv_token for msg in messages: + if hasattr(msg, 'header'): + if msg.header.flags.vital: + sent_vital += 1 + msg.header.seq = sent_vital packet.messages.append(msg) - print(f"sending {packet.pack()}") + packet.header.ack = got_vital sock.sendto(packet.pack(), dest_srv) # TODO: we should be able to set this @@ -40,20 +65,42 @@ send_msg(ctrl_token) while True: data, addr = sock.recvfrom(NET_MAX_PACKETSIZE) packet = parse7(data) - print(packet) for msg in packet.messages: + if hasattr(msg, 'header'): + if msg.header.flags.vital and not msg.header.flags.resend: + got_vital = (got_vital + 1) % NET_MAX_SEQUENCE + if msg.header.seq in got_seqs: + pass + # continue + got_seqs.add(msg.header.seq) + if msg.message_name == 'token': srv_token = msg.response_token - print(f"got server token {srv_token}") ctrl_connect = CtrlConnect() ctrl_connect.response_token = my_token send_msg(ctrl_connect) - if msg.message_name == 'accept': - # TODO: make these default values - send_msg(MsgInfo( - version = "0.7 802f1be60a05665f", - client_version = 1797 - )) - print("got accept") + elif msg.message_name == 'accept': + info = MsgInfo() + info.header.flags.vital = True + send_msg(info) + elif msg.message_name == 'map_change': + map_info = msg + req = MsgRequestMapData() + req.header.flags.vital = True + send_msg(req) + elif msg.message_name == 'map_data': + downloaded_chunks += 1 + downloaded_bytes += msg.header.size + progress(downloaded_bytes, map_info.size) + if downloaded_bytes >= map_info.size: + print(f"finished downloading {map_info.name}") + continue + if downloaded_chunks % map_info.num_response_chunks_per_request == 0: + req = MsgRequestMapData() + req.header.flags.vital = True + send_msg(req) + elif msg.message_name == 'close': + print("disconnected") + exit(0)