def login(self, usr, pwd, server): error_counter = 0 if not config["behavior"][ "unlimited_retry"] else -0x3fffffff # min(int32) while True: salt = self.challenge(server, time.time() + random.randint(0xF, 0xFF)) packet = make_packet(salt, usr, pwd, config["cqu_server"]["mac"]) self.socket.sendto(packet, (server, 61440)) data, address = self.socket.recvfrom(1024) if address == (server, 61440) and data[:1] == b"\x04": log("登录成功") break else: if data.startswith(b"\x05\x00\x00\x05\x03"): log("帐号密码错误,无效的帐号密码已清除", error=True) config.reset() exit() elif data.startswith(b"\x05\x00\x00\x05\x04"): log("帐号已欠费,请充值后再次登录", error=True) exit() elif data.startswith(b"\x05\x00\x00\x05\x05"): log("帐号已停机,请前往管理页面开机", error=True) exit() else: log("登录失败,原因未知", error=True) error_counter += 1 if error_counter >= 5: exit() return data[23:39], salt
def keep_alive(self, salt, ptail, password, server): _ = self.send_heartbeat_packet(build_heartbeat_packet( 0, b"\x00" * 4, 1, True), check_start=True) i = 1 tail = b"\x00" * 4 for j in (1, 3): tail = self.send_heartbeat_packet(build_heartbeat_packet( i, tail, j, False), check_start=True) i += 1 while True: try: time.sleep(20) self.keep_alive1(salt, ptail, password) for j in (1, 3): tail = self.send_heartbeat_packet(build_heartbeat_packet( i, tail, j, False), check_start=False) i = (i + 1) % 127 socket.gethostbyname("www.taobao.com") reset_error_count() except Exception: log("网络断开,尝试重新登陆", error=True) return
def send_heartbeat_packet(self, packet, check_start=False) -> bytes: heartbeat_error_count = 0 while True: self.socket.sendto(packet, (config["cqu_server"]["server"], 61440)) if heartbeat_error_count > 10: if config["behavior"]["unlimited_retry"]: raise ConnectionResetError("重新登录") else: exit() try: data, _ = self.socket.recvfrom(1024) except socket.timeout: log("心跳包发送失败,是否在其他地方登录?", warning=True) time.sleep(3) heartbeat_error_count += 1 continue if check_start is True: if not data.startswith(b"\x07"): log("心跳包发送失败", warning=True) time.sleep(3) heartbeat_error_count += 1 continue return data[16:20]
def __init__(self): self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: self.socket.bind(("0.0.0.0", 61440)) except OSError: log("绑定端口失败,是否有其他drcom正在运行?") exit() self.socket.settimeout(3)
def challenge(self, svr, ran): while True: t = struct.pack("<H", int(ran) % 0xFFFF) self.socket.sendto(b"\x01\x02" + t + b"\x09" + b"\x00" * 15, (svr, 61440)) try: data, address = self.socket.recvfrom(1024) except Exception: log("尝试与服务器通信失败,物理连接可能出现问题", error=True) continue if address == (svr, 61440) and data[:1] == b"\x02": break else: log("尝试与服务器通信时发生未知错误", error=True) continue return data[4:8]
def __main__(self): username = config["user_info"]["username"] password = config["user_info"]["password"] server = config["cqu_server"]["server"] while True: try: tail, salt = self.login(username, password, server) except Exception as e: log("登录失败 " + str(e), error=True) continue check_update('cqu-de') # 体面的退出 try: self.empty_socket_buffer() self.keep_alive1(salt, tail, password) self.keep_alive(salt, tail, password, server) except KeyboardInterrupt: log("de已完全退出,再见!") sys.exit()