import socket import threading from pathlib import Path import sys # ----- GLOBALS & LOCKS ----- # # This prevents the Receiver and Sender from printing over each other print_lock = threading.Lock() # ----- KNOWN CONNECTION FILE LOGIC (Compatibility Kept) ----- # def read_specific_line(filename, line_number): try: with open(filename, 'r') as file: for index, line in enumerate(file): if index == line_number: current_line = line.rsplit(": ", 1) return current_line[1].strip() except Exception: return None return None def known_connection_file(mode, nick=None, ip_addr=None, no_of_ip_chosen=None): file_path = Path("known_connections.txt") if not file_path.exists(): with open(file_path, 'w') as f: f.write("") if mode == "read": with open(file_path, 'r') as f: for i, line in enumerate(f, 1): print(f"[{i}] {line}", end="") elif mode == "select": return read_specific_line(file_path, no_of_ip_chosen - 1) elif mode == "write": with open(file_path, 'a') as f: f.write(f"{nick}: {ip_addr}\n") elif mode == "clear": with open(file_path, 'w') as f: f.write("") # ----- THE RECEIVER THREAD (Runs in background) ----- # def background_receiver(): host = '0.0.0.0' port = 443 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: s.bind((host, port)) except PermissionError: with print_lock: print("\n[!] ERROR: Process Needs Elevation.") return s.listen(5) while True: c, addr = s.accept() with print_lock: print(f"\n[+] {addr}") while True: try: data = c.recv(1024).decode() if not data: break with print_lock: # The \r ensures we clear any partially typed input line print(f"\r [R] {addr[0]}: {data}\n > ", flush=True) except Exception: break c.close() # ----- THE MAIN SENDER LOGIC ----- # def port_selection(): with print_lock: print("\n" + "="*60) print(" P7-InfraNET CLRadio-Hybrid A-1-ii Integra | P7MJ") print("="*60) print("[1] Connect to IPv4") print("[2] Wait for a connection") print("[x] Exit App") choice = input(" > ") if choice == "x": sys.exit() if choice == "1": known_connection_file("read") print("[n] New profile\n[d] Delete all profiles") sub_choice = input("\n > ") if num.isdigit(): return known_connection_file("select", no_of_ip_chosen=int(num)) elif sub_choice == "n": nick = input("Profile Nickname > ") ip = input("Profile IPv4 > ") known_connection_file("write", nick, ip) return None elif sub_choice == "3": areusure = input("ARE YOU SURE? This is irreversible! [Yes/cancel]") if areusure == "Yes": known_connection_file("clear") return None if choice == "2": print("Waiting...", end = "\r") return None def run_app(): # Start background receiver immediately recv_thread = threading.Thread(target=background_receiver, daemon=True) recv_thread.start() while True: target_ip = None while not target_ip: target_ip = port_selection() try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) s.connect((target_ip, 443)) s.settimeout(None) with print_lock: print(f"\r[!] Connected to {target_ip}. Type 'exit' to disconnect.", flush=True) while True: msg = input(" [S] ") if msg.lower() == 'exit': break try: s.send(msg.encode()) except Exception: print("[!] FATAL: Connection lost at second to last message!") break s.close() except Exception as e: print(f"[!] Could not connect to {target_ip}: {e}") if __name__ == '__main__': while True: try: run_app() except KeyboardInterrupt: input("\n[!] User terminated application! Press ENTER to continue...") sys.exit(0)