From 55fc21deda75e89de3158483ee31fb640db30d70 Mon Sep 17 00:00:00 2001 From: Emil Sonesson <59544183+piplarsson@users.noreply.github.com> Date: Thu, 21 Aug 2025 16:40:49 +0200 Subject: [PATCH 1/5] Update main.py --- main.py | 349 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 282 insertions(+), 67 deletions(-) diff --git a/main.py b/main.py index 929d21f..073e712 100644 --- a/main.py +++ b/main.py @@ -1,105 +1,320 @@ -import random -import socket +import sys +import re +import secrets import string +import random import calendar -from ctypes import windll +import webbrowser +import subprocess +from dataclasses import dataclass +from pathlib import Path +from datetime import datetime, date + +# ============================= +# Configuration +# ============================= + +OUTPUT_FILE = Path("account_details.txt") +PASSWORD_LENGTH = 12 +DOB_YEAR_MIN = 1970 +DOB_YEAR_MAX = 2004 # reasonable adult range + +TEMP_MAIL_URL = "https://temp-mail.org/" +EPIC_SIGNUP_URL = "https://www.epicgames.com/id/register" + +SAFE_PUNCT = "!@#$%^&*()-_=+[]{}:;,./?" +PASSWORD_ALPHABET = string.ascii_letters + string.digits + SAFE_PUNCT + +# Common English names +FIRST_NAMES = [ + "Oliver", "George", "Harry", "Jack", "Noah", + "Olivia", "Amelia", "Isla", "Ava", "Mia", + "Liam", "Emma", "Sophia", "Charlotte", "James", + "Benjamin", "Lucas", "Henry", "Ethan", "Grace" +] +LAST_NAMES = [ + "Smith", "Johnson", "Williams", "Brown", "Jones", + "Miller", "Davis", "Garcia", "Rodriguez", "Wilson", + "Taylor", "Thomas", "Moore", "Martin", "Jackson" +] + +ENGLISH_COUNTRIES = [ + "United States", + "United Kingdom", + "Canada", + "Australia", + "Ireland", + "New Zealand", +] + +DEFAULT_COUNTRY = "United States" + +# ============================= +# OS helpers (topmost & clipboard) +# ============================= + +def set_window_always_on_top_safe() -> None: + """Make console 'always on top' on Windows without moving/resizing.""" + if sys.platform != "win32": + return + try: + from ctypes import windll # type: ignore + HWND_TOPMOST = -1 + SWP_NOMOVE = 0x0002 + SWP_NOSIZE = 0x0001 + flags = SWP_NOMOVE | SWP_NOSIZE + hwnd = windll.user32.GetForegroundWindow() + if hwnd: + windll.user32.SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, flags) + except Exception: + pass + +def copy_to_clipboard(text: str) -> bool: + """ + Copy text to clipboard. + - Windows: uses 'clip' + - Others: tries tkinter if available + """ + try: + if sys.platform == "win32": + p = subprocess.Popen(["clip"], stdin=subprocess.PIPE, text=True) + p.communicate(text) + return p.returncode == 0 + else: + try: + import tkinter as tk # type: ignore + r = tk.Tk() + r.withdraw() + r.clipboard_clear() + r.clipboard_append(text) + r.update() + r.destroy() + return True + except Exception: + return False + except Exception: + return False + +# ============================= +# Validation +# ============================= -def set_window_always_on_top(): - HWND_TOPMOST = -1 - HWND = windll.user32.GetForegroundWindow() - windll.user32.SetWindowPos(HWND, HWND_TOPMOST, 0, 0, 0, 0, 0x0001) +EMAIL_REGEX = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$") -def convert_month_number(month_number): +def is_valid_email(email: str) -> bool: + return bool(EMAIL_REGEX.match(email.strip())) + +# ============================= +# Dates & names +# ============================= + +def convert_month_number(month_number: int) -> str: return calendar.month_abbr[month_number] -def generate_name(): - prefixes = ["Ava", "Eli", "Emma", "Liam", "Olivia", "Noah", "Isabella", "Sophia", "Mia", "Charlotte"] - suffixes = ["n", "lia", "n", "am", "h", "n", "a", "h", "a", "e"] +def generate_valid_date(min_year: int = DOB_YEAR_MIN, max_year: int = DOB_YEAR_MAX) -> str: + """Return a valid date string (DD/Mon/YYYY) within the given range.""" + year = secrets.choice(range(min_year, max_year + 1)) + month = secrets.choice(range(1, 13)) + while True: + day = secrets.choice(range(1, 32)) + try: + d = date(year, month, day) + return f"{d.day:02d}/{convert_month_number(d.month)}/{d.year}" + except ValueError: + continue + +def generate_names() -> tuple[str, str]: + """English first/last name.""" + return secrets.choice(FIRST_NAMES), secrets.choice(LAST_NAMES) - prefix = random.choice(prefixes) - suffix = random.choice(suffixes) +def sanitize_display_name(base: str) -> str: + """ + Conservative display name rules: + - 3–16 characters + - starts with a letter + - a–z, 0–9, underscore only + """ + allowed = string.ascii_lowercase + string.digits + "_" + base = base.lower() - return prefix + suffix + if not base or not base[0].isalpha(): + base = "a" + base + filtered = [ch if ch in allowed else "_" for ch in base] + s = "".join(filtered) -def generate_date(): - day = random.randint(1, 31) - month = random.randint(1, 12) - year = 2000 + s = s[:16] + while len(s) < 3: + s += str(secrets.randbelow(10)) + return s - return f"{day:02d}/{convert_month_number(month)}/{year}" +def generate_display_name(first: str, last: str) -> str: + """Builds a likely-unique, policy-friendly display name.""" + base = first + last + str(secrets.randbelow(9000) + 1000) # 1000–9999 + return sanitize_display_name(base) +# ============================= +# Passwords +# ============================= -def generate_display_name(): - first_name = generate_name() - last_name = generate_name() - numbers = random.randint(1000, 9999) +def generate_password(length: int = PASSWORD_LENGTH) -> str: + """ + Strong password with: + - minimum 10 chars + - at least 1 lowercase, 1 uppercase, 1 digit, 1 special + """ + if length < 10: + length = 10 - display_name = first_name + last_name + str(numbers) - first_last_name = first_name + " " + last_name + req = [ + secrets.choice(string.ascii_lowercase), + secrets.choice(string.ascii_uppercase), + secrets.choice(string.digits), + secrets.choice(SAFE_PUNCT), + ] + remaining = [secrets.choice(PASSWORD_ALPHABET) for _ in range(length - len(req))] + chars = req + remaining + secrets.SystemRandom().shuffle(chars) + return "".join(chars) - return display_name, first_last_name +# ============================= +# Dataclass & I/O +# ============================= +@dataclass +class AccountDetails: + email: str + first_name: str + last_name: str + display_name: str + date_str: str + password: str + country: str + created_at: str -def generate_password(length): - characters = string.ascii_letters + string.digits + string.punctuation - password = ''.join(random.choice(characters) for _ in range(length)) - return password + def to_text_block(self) -> str: + lines = [ + f"Email: {self.email}", + f"First name: {self.first_name}", + f"Last name: {self.last_name}", + f"Create password: {self.password}", + f"Add a display name: {self.display_name}", + f"Date: {self.date_str}", + f"Country: {self.country}", + f"Created: {self.created_at}", + "-" * 31, + ] + return "\n".join(lines) +def append_to_file(block: str, file_path: Path = OUTPUT_FILE) -> None: + file_path.parent.mkdir(parents=True, exist_ok=True) + with file_path.open("a", encoding="utf-8") as f: + f.write(block + "\n") -def generate_epic_games_code(email): - # Generate a random display name, its corresponding first and last name, and a date - display_name, first_last_name = generate_display_name() - date = generate_date() +# ============================= +# Generation +# ============================= - # Get the computer's IP address - ip_address = socket.gethostbyname(socket.gethostname()) +def generate_account(email: str, country: str) -> AccountDetails: + first, last = generate_names() + display = generate_display_name(first, last) + dob = generate_valid_date() + pwd = generate_password(PASSWORD_LENGTH) + now_iso = datetime.now().isoformat(timespec="seconds") + return AccountDetails( + email=email.strip(), + first_name=first, + last_name=last, + display_name=display, + date_str=dob, + password=pwd, + country=country, + created_at=now_iso, + ) - # Generate a random password with a length of 10 characters - password = generate_password(10) +# ============================= +# Interactive flow +# ============================= - # Save the account details to a text file - with open("../python non virus/account_details.txt", "a") as file: - file.write("Email: " + email + "\n") - file.write("Display Name: " + display_name + "\n") - file.write("First and Last Name: " + first_last_name + "\n") - file.write("Date: " + date + "\n") - file.write("Password: " + password + "\n") - file.write("-------------------------------\n") +def choose_country() -> str: + print("\nSelect country (press Enter for default):") + for i, c in enumerate(ENGLISH_COUNTRIES, start=1): + default_mark = " (default)" if c == DEFAULT_COUNTRY else "" + print(f"{i}. {c}{default_mark}") - # Print the generated details - print("-------------------------") - print("Email:", email) - print("Generated Display Name:", display_name) - print("Generated First and Last Name:", first_last_name) - print("Generated Date:", date) - print("Generated Password:", password) - print("-------------------------") + raw = input("Choice [1-6, Enter=default]: ").strip() + if raw.isdigit(): + idx = int(raw) + if 1 <= idx <= len(ENGLISH_COUNTRIES): + return ENGLISH_COUNTRIES[idx - 1] + return DEFAULT_COUNTRY -def main(): - set_window_always_on_top() +def guide_copy_field(label: str, value: str) -> None: + """Show value and copy it to clipboard when user presses Enter.""" + print(f"\n{label}: {value}") + input("Press Enter to copy to clipboard... ") + ok = copy_to_clipboard(value) + if ok: + print("✅ Copied! Paste it in the form (Ctrl+V).") + else: + print("⚠️ Could not copy automatically. Please copy manually from above.") + +def menu_loop() -> None: + set_window_always_on_top_safe() while True: - print("Please select an option:") - print("1. Epic Games") + print("\nPlease select an option:") + print("1. Create new account data (optimized for Epic form)") print("2. Quit") - choice = input("Enter your choice: ") + choice = input("Enter your choice: ").strip() if choice == "1": - print("Click here to generate your temporary email for your epic account: 'https://temp-mail.org/'") - email = input("Enter your temporary generated email address: ") - generate_epic_games_code(email) - generate_more = input("Do you want to generate more accounts? (Y/N): ") - if generate_more.upper() == "N": + # 1) open Temp-Mail + print("Opening temporary email service...") + webbrowser.open(TEMP_MAIL_URL, new=2) + + # 2) ask for email + email = input("Paste your temporary email address here: ").strip() + if not is_valid_email(email): + print("Invalid email format. Try again.\n") + continue + + # 3) choose an English-speaking country (default US) + country = choose_country() + + # 4) generate details + acc = generate_account(email, country) + block = acc.to_text_block() + append_to_file(block) + + # 5) open Epic signup + print("Opening Epic signup...") + webbrowser.open(EPIC_SIGNUP_URL, new=2) + + print("\n--- Guided fill (press Enter to copy each field) ---") + guide_copy_field("Email address", acc.email) + guide_copy_field("First name", acc.first_name) + guide_copy_field("Last name", acc.last_name) + guide_copy_field("Create password", acc.password) + guide_copy_field("Add a display name", acc.display_name) + print(f"\nCountry: {acc.country} (pick it in the dropdown if not preselected).") + print("\nRemember to agree to the Terms of Service before clicking Continue.") + + more = input("\nGenerate another? (Y/N): ").strip().upper() + if more == "N": break + elif choice == "2": break else: - print("Invalid choice. Please try again.") + print("Invalid choice. Please try again.\n") input("Press Enter to exit...") -# Execute the main function +# ============================= +# Entrypoint +# ============================= + if __name__ == "__main__": - main() + menu_loop() From b601f4e20a7df463a5d725a2a9296ec62282b850 Mon Sep 17 00:00:00 2001 From: Emil Sonesson <59544183+piplarsson@users.noreply.github.com> Date: Thu, 21 Aug 2025 16:41:29 +0200 Subject: [PATCH 2/5] Update requirements.txt --- requirements.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bebaa03..afa5835 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,4 @@ -requests +# Requirements for Epic Account Generator +# Works with Python 3.10+ +# All modules are from the Python standard library. +# On Linux/macOS, install tkinter separately if needed. From 7029338f401ab42154b885dae063db2074348abd Mon Sep 17 00:00:00 2001 From: Emil Sonesson <59544183+piplarsson@users.noreply.github.com> Date: Thu, 21 Aug 2025 16:45:34 +0200 Subject: [PATCH 3/5] Update README.md --- README.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2b89345..04eb095 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,66 @@ -# EPICACCGEN -Epic Games Account Generator +# Epic Account Data Generator +A Python utility that generates **realistic account details** optimized for the Epic Games signup form. +It helps you quickly fill in the registration page by: +- Opening **Temp-Mail** in your browser to get a disposable email. +- Opening the **Epic Games signup page**. +- Generating a random **first name**, **last name**, **display name**, **strong password**, and **birth date**. +- Copying each field to your clipboard step by step so you can paste directly into the signup form. -Using Pythons Latest Version to run Either click main.py or open cmd and type ---- python main.py +--- + +## ✨ Features +- Random **English names** (first & last). +- Display name follows Epic’s typical rules (3–16 chars, starts with a letter, only `a–z`, `0–9`, `_`). +- Strong password with at least 1 uppercase, 1 lowercase, 1 digit, and 1 special character. +- Valid random birth date within a reasonable adult age range (1970–2004 by default). +- Country optimized for **English-speaking users** (default: United States, optional: UK, Canada, Australia, Ireland, New Zealand). +- Stores all generated account details in `account_details.txt`. +- Guided workflow: press Enter to copy each value to your clipboard. + +--- + +## 🚀 How It Works +1. Choose `1` in the console menu. +2. Your browser will open **Temp-Mail** → copy a temporary email. +3. Paste the email into the program. +4. The program generates account details. +5. The Epic Games signup page opens automatically. +6. The program shows each field (Email → First name → Last name → Password → Display name). + - Press **Enter** to copy it to your clipboard. + - **Paste** into the Epic signup form (Ctrl+V). +7. Continue through the form, set your country, agree to ToS, and create the account. + +--- + +## 🛠 Requirements +- **Python 3.10+** (tested with 3.12 and 3.13) +- Works on **Windows**, **Linux**, and **macOS**. +- No external packages needed – uses only the Python standard library. + +### Clipboard support: +- Windows → uses built-in `clip` command. +- Linux/macOS → requires `tkinter` (often preinstalled). + - Ubuntu/Debian: `sudo apt install python3-tk` + - Fedora: `sudo dnf install python3-tkinter` + +--- + +## ▶️ Run the Program +```bash +python main.py +``` +```bash +📂 Project Structure +bash +Kopiera +Redigera +. +├── main.py # Main script +├── account_details.txt # Generated accounts (auto-created) +├── README.md # This documentation +``` +⚠️ Disclaimer +This tool is for educational and personal testing purposes only. +Using fake or disposable data to create accounts may violate Epic Games’ Terms of Service. +Use responsibly. From f8a7908de093fa56273a88c788ee4098280a5472 Mon Sep 17 00:00:00 2001 From: Emil Sonesson <59544183+piplarsson@users.noreply.github.com> Date: Thu, 21 Aug 2025 16:45:55 +0200 Subject: [PATCH 4/5] Delete .github/workflows directory --- .github/workflows/python-package.yml | 40 ---------------------------- 1 file changed, 40 deletions(-) delete mode 100644 .github/workflows/python-package.yml diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml deleted file mode 100644 index e56abb6..0000000 --- a/.github/workflows/python-package.yml +++ /dev/null @@ -1,40 +0,0 @@ -# This workflow will install Python dependencies, run tests and lint with a variety of Python versions -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python - -name: Python package - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: ["3.9", "3.10", "3.11"] - - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python -m pip install flake8 pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest - run: | - pytest From c6c049cf682417841a44e1a824b70871f93b9e3d Mon Sep 17 00:00:00 2001 From: Emil Sonesson <59544183+piplarsson@users.noreply.github.com> Date: Thu, 21 Aug 2025 16:49:06 +0200 Subject: [PATCH 5/5] Update README.md --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 04eb095..b5b8cdc 100644 --- a/README.md +++ b/README.md @@ -50,17 +50,15 @@ It helps you quickly fill in the registration page by: ```bash python main.py ``` + +## 📂 Project Structure ```bash -📂 Project Structure -bash -Kopiera -Redigera -. ├── main.py # Main script ├── account_details.txt # Generated accounts (auto-created) ├── README.md # This documentation ``` -⚠️ Disclaimer + +## ⚠️ Disclaimer This tool is for educational and personal testing purposes only. Using fake or disposable data to create accounts may violate Epic Games’ Terms of Service. Use responsibly.