import socket
import ssl
import threading
import ipaddress
import time
import random
from queue import Queue
import os

def load_scanned_blocks():
    scanned = set()
    if os.path.exists("scanned_contabo_blocks.txt"):
        try:
            with open("scanned_contabo_blocks.txt", "r") as f:
                for line in f:
                    scanned.add(line.strip())
        except:
            pass
    return scanned

def save_scanned_block(block):
    try:
        with open("scanned_contabo_blocks.txt", "a") as f:
            f.write(block + "\n")
    except:
        pass

def get_master_ranges(scanned_blocks):
    print("\033[93m[+] Generating Contabo Very Old Legacy Batch...\033[0m")
    
    base_blocks = [
        "5.189.0.0/16", "173.212.0.0/16", "176.9.0.0/16", "178.63.0.0/16",
        "144.76.0.0/16", "148.251.0.0/16", "188.40.0.0/16", "213.239.0.0/16",
        "46.4.0.0/16", "62.113.0.0/16", "94.130.0.0/16", "95.216.0.0/16"
    ]
    
    extra_ranges = []
    contabo_very_old = [5,173,176,178,144,148,188,213,46,62,94,95,138,159,167,185,193,194,212,217,37,80,81,82,83,84,85,86,87,88,89,90,91,92,93,217,37,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96]
    
    for base in contabo_very_old:
        for sub in range(0, 256, 1):
            cidr = f"{base}.{sub}.0.0/16"
            if cidr in scanned_blocks:
                continue
            extra_ranges.append(cidr)
            if sub % 2 == 0:
                extra_ranges.append(f"{base}.{sub}.0.0/15")
            if sub % 4 == 0:
                extra_ranges.append(f"{base}.{sub}.0.0/14")
            if sub % 7 == 0:
                extra_ranges.append(f"{base}.{sub}.0.0/12")
    
    ranges = list(dict.fromkeys(base_blocks + extra_ranges))
    random.shuffle(ranges)
    print(f"\033[92m[+] Loaded: {len(ranges):,} Very Old Contabo Legacy Ranges\033[0m")
    return ranges

THREADS = 990
TIMEOUT = 0.68
queue = Queue(maxsize=95000)
lock = threading.Lock()
ssl_context = ssl._create_unverified_context()

def nersi_harvester():
    while True:
        ip = queue.get()
        if ip is None:
            break
        target = str(ip)
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            sock.settimeout(TIMEOUT)
           
            if sock.connect_ex((target, 2087)) == 0:
                with ssl_context.wrap_socket(sock, server_hostname=target, do_handshake_on_connect=False) as ssock:
                    ssock.do_handshake()
                    url = f"https://{target}:2087"
                    with lock:
                        print(f"\033[92m[OPEN] → {url}\033[0m")
                        with open("contabo_open_results.txt", "a") as f:
                            f.write(url + "\n")
        except:
            pass
        finally:
            queue.task_done()

def main():
    print("\033[38;5;208m\033[1m[*] CONTABOSERVER.NET VERY OLD LEGACY UNLIMITED - NEW BATCH\033[0m")
    print("[*] IP Sangat Lama + Unscanned\n")
   
    for _ in range(THREADS):
        t = threading.Thread(target=nersi_harvester, daemon=True)
        t.start()
    
    cycle = 0
    while True:
        cycle += 1
        print(f"\033[93m[*] Cycle {cycle} - Loading very old unscanned Contabo blocks...\033[0m")
        
        scanned = load_scanned_blocks()
        ranges = get_master_ranges(scanned)
        
        total_scanned = 0
        for r in ranges:
            with lock:
                print(f"[*] Scanning: {r}")
            
            save_scanned_block(r)
            
            try:
                net = ipaddress.ip_network(r)
                for i, ip in enumerate(net):
                    if i % 6 == 0:
                        queue.put(ip)
                        total_scanned += 1
                    if queue.qsize() > 85000:
                        time.sleep(0.10)
            except:
                continue
        
        print(f"\033[92m[+] Cycle {cycle} selesai | IP dicek: {total_scanned:,}\033[0m")
        print("[*] Melanjutkan ke legacy sangat lama berikutnya...\n")
        time.sleep(5)

if __name__ == "__main__":
    main()