rooting-future / tools /LicenseKeyGen.py
mtornani's picture
Initial HF Spaces deployment (clean branch without large binaries)
38f9c15
"""
Rooting Future - License Key Generator Tool
Standalone GUI tool for generating license keys from HWID.
Build standalone EXE:
pyinstaller --onefile --windowed --name LicenseKeyGen tools/LicenseKeyGen.py
"""
import hashlib
import os
import sys
import tkinter as tk
from tkinter import ttk, messagebox
from datetime import datetime
import pyperclip # pip install pyperclip
# =============================================================================
# LICENSE ALGORITHM (Must match license_manager.py)
# =============================================================================
def generate_license_key(owner_email: str, machine_identifier: str) -> str:
"""
Generate a valid license key for a given user and machine.
Algorithm must match license_manager.py
"""
# Normalize machine ID (remove dashes and spaces)
clean_hwid = machine_identifier.replace("-", "").replace(" ", "").strip().upper()
# Secret salt (must match license_manager.py)
secret_salt = os.environ.get("LICENSE_SALT", "coca-cola-secret-recipe-2026")
# Create unique base string
raw_string = f"{clean_hwid}:{owner_email}:{secret_salt}"
# Generate hash and take first 24 characters
return hashlib.sha256(raw_string.encode()).hexdigest().upper()[:24]
# =============================================================================
# GUI APPLICATION
# =============================================================================
class LicenseKeyGenApp:
def __init__(self, root):
self.root = root
self.root.title("Rooting Future - License Key Generator")
self.root.geometry("550x450")
self.root.resizable(False, False)
# Set icon if available
try:
self.root.iconbitmap("static/favicon.ico")
except:
pass
# Configure style
self.style = ttk.Style()
self.style.configure("Title.TLabel", font=("Segoe UI", 14, "bold"))
self.style.configure("Key.TLabel", font=("Consolas", 12, "bold"), foreground="#2e7d32")
self.style.configure("Big.TButton", font=("Segoe UI", 10))
self.create_widgets()
def create_widgets(self):
# Main frame
main_frame = ttk.Frame(self.root, padding="20")
main_frame.pack(fill=tk.BOTH, expand=True)
# Title
title_label = ttk.Label(
main_frame,
text="License Key Generator",
style="Title.TLabel"
)
title_label.pack(pady=(0, 20))
# Description
desc_label = ttk.Label(
main_frame,
text="Genera chiavi di licenza per clienti Rooting Future.\n"
"Inserisci l'email del cliente e il codice macchina (HWID).",
justify=tk.CENTER
)
desc_label.pack(pady=(0, 20))
# Form frame
form_frame = ttk.Frame(main_frame)
form_frame.pack(fill=tk.X, pady=10)
# Email
ttk.Label(form_frame, text="Email Cliente:").grid(row=0, column=0, sticky=tk.W, pady=5)
self.email_var = tk.StringVar()
self.email_entry = ttk.Entry(form_frame, textvariable=self.email_var, width=45)
self.email_entry.grid(row=0, column=1, pady=5, padx=(10, 0))
# HWID
ttk.Label(form_frame, text="Codice Macchina (HWID):").grid(row=1, column=0, sticky=tk.W, pady=5)
self.hwid_var = tk.StringVar()
self.hwid_entry = ttk.Entry(form_frame, textvariable=self.hwid_var, width=45)
self.hwid_entry.grid(row=1, column=1, pady=5, padx=(10, 0))
# HWID hint
hint_label = ttk.Label(
form_frame,
text="Formato: XXXX-XXXX-XXXX-XXXX (con o senza trattini)",
font=("Segoe UI", 8),
foreground="gray"
)
hint_label.grid(row=2, column=1, sticky=tk.W, padx=(10, 0))
# Generate button
gen_button = ttk.Button(
main_frame,
text="Genera Chiave Licenza",
command=self.generate_key,
style="Big.TButton"
)
gen_button.pack(pady=20)
# Result frame
result_frame = ttk.LabelFrame(main_frame, text="Chiave Generata", padding="10")
result_frame.pack(fill=tk.X, pady=10)
self.key_var = tk.StringVar(value="---")
self.key_label = ttk.Label(
result_frame,
textvariable=self.key_var,
style="Key.TLabel"
)
self.key_label.pack(pady=10)
# Copy button
copy_frame = ttk.Frame(result_frame)
copy_frame.pack()
self.copy_button = ttk.Button(
copy_frame,
text="Copia negli Appunti",
command=self.copy_key,
state=tk.DISABLED
)
self.copy_button.pack(side=tk.LEFT, padx=5)
self.save_button = ttk.Button(
copy_frame,
text="Salva Log",
command=self.save_log,
state=tk.DISABLED
)
self.save_button.pack(side=tk.LEFT, padx=5)
# Status bar
self.status_var = tk.StringVar(value="Pronto")
status_bar = ttk.Label(
main_frame,
textvariable=self.status_var,
relief=tk.SUNKEN,
anchor=tk.W
)
status_bar.pack(fill=tk.X, side=tk.BOTTOM, pady=(10, 0))
# Store last generated info for logging
self.last_email = ""
self.last_hwid = ""
self.last_key = ""
def generate_key(self):
email = self.email_var.get().strip()
hwid = self.hwid_var.get().strip()
# Validation
if not email:
messagebox.showerror("Errore", "L'email e obbligatoria!")
self.email_entry.focus()
return
if "@" not in email or "." not in email:
messagebox.showerror("Errore", "Email non valida!")
self.email_entry.focus()
return
if not hwid:
messagebox.showerror("Errore", "Il codice macchina (HWID) e obbligatorio!")
self.hwid_entry.focus()
return
# Clean HWID for validation
clean_hwid = hwid.replace("-", "").replace(" ", "")
if len(clean_hwid) < 8:
messagebox.showerror("Errore", "Codice macchina troppo corto (minimo 8 caratteri)!")
self.hwid_entry.focus()
return
try:
# Generate key
license_key = generate_license_key(email, hwid)
# Format key for display (groups of 6)
formatted_key = "-".join([license_key[i:i+6] for i in range(0, len(license_key), 6)])
# Update UI
self.key_var.set(formatted_key)
self.copy_button.config(state=tk.NORMAL)
self.save_button.config(state=tk.NORMAL)
self.status_var.set(f"Chiave generata per {email}")
# Store for logging
self.last_email = email
self.last_hwid = hwid
self.last_key = license_key
except Exception as e:
messagebox.showerror("Errore", f"Errore nella generazione: {str(e)}")
def copy_key(self):
if self.last_key:
try:
pyperclip.copy(self.last_key)
self.status_var.set("Chiave copiata negli appunti!")
except:
# Fallback without pyperclip
self.root.clipboard_clear()
self.root.clipboard_append(self.last_key)
self.status_var.set("Chiave copiata negli appunti!")
def save_log(self):
if not self.last_key:
return
log_file = "license_log.txt"
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"{timestamp} | {self.last_email} | {self.last_hwid} | {self.last_key}\n"
try:
with open(log_file, "a", encoding="utf-8") as f:
f.write(log_entry)
self.status_var.set(f"Log salvato in {log_file}")
messagebox.showinfo("Salvato", f"Log salvato in {log_file}")
except Exception as e:
messagebox.showerror("Errore", f"Impossibile salvare: {str(e)}")
# =============================================================================
# MAIN
# =============================================================================
def main():
root = tk.Tk()
app = LicenseKeyGenApp(root)
root.mainloop()
if __name__ == "__main__":
main()