Skip to content
  • 0 Unread 0
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Donate
Collapse

Plutonium

  1. Home
  2. Launcher Support
  3. PlutoniumX Auto Game Launcher

PlutoniumX Auto Game Launcher

Scheduled Pinned Locked Moved Launcher Support
11 Posts 4 Posters 1.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Former User? Offline
    A Former User? Offline
    A Former User
    wrote on last edited by
    #2

    I got you a rep

    1 Reply Last reply
    0
    • A Former User? Offline
      A Former User? Offline
      A Former User
      wrote on last edited by
      #3

      Thank you! I will post a link for it soon. Just updating one small thing on it tonight

      Littlegods 1 Reply Last reply
      0
      • A Former User? A Former User

        Thank you! I will post a link for it soon. Just updating one small thing on it tonight

        Littlegods Offline
        Littlegods Offline
        Littlegods
        wrote on last edited by
        #4

        @MultiplayerXGES I donโ€™t want to bring you down, but I donโ€™t think this is a good way to publish something like this here. The Plutonium launcher is the one that should be used, not one created by some random person when we donโ€™t even know how itโ€™s being executed.

        1 Reply Last reply
        1
        • A Former User? Offline
          A Former User? Offline
          A Former User
          wrote on last edited by A Former User
          #5

          I understand your concern PlutoniumX is simply a standalone launcher that makes a nicer interface and makes it faster and easier to launch each game. Instead of having to set paths like the lan launcher PlutoniumX does everything for you. All you do is add the executable into your main Plutonium/ folder and you are ready to go ๐Ÿ˜Ž I also added a program I made that finds your ip4 address and makes a connect command for you automatically as well It's included in the file BTW I am MultiplayerX from GoldenEye Source and I have been a mapper and gameshark hacker for over 20 years. You are more than safe with anything I release ๐Ÿ˜‰ Enjoy! PlutoniumX Auto Launcher : https://drive.usercontent.google.com/download?id=1cZYZiJGOinmGv5F4XBcrAUCLuOCtK1ve&export=download&authuser=0
          px_ui.PNG
          px_ui2.PNG

          1 Reply Last reply
          0
          • A Former User? Offline
            A Former User? Offline
            A Former User
            wrote on last edited by
            #6

            Oh i did forget to mention. The program will save any new username you enter and any game you launch will save whatever paths the program finds your valid game files inside the .INI file You can delete the file or edit out the paths using notepad in the INI file if you need to change your name without rescanning for the game but honestly that's not necessary because the program is very fast and doesn't take that long to lock in where your files are as long as you put the program in your main Plutonium folder ๐Ÿ˜Ž MultiX

            1 Reply Last reply
            0
            • DrSkum88 Offline
              DrSkum88 Offline
              DrSkum88
              wrote on last edited by
              #7

              A closed source UI that doesn't add anything? Sounds like using this is just asking for malware.
              Just use the basic cli commands plutonium supports to make game shortcuts if that's what you want. No reason to use this.

              1 Reply Last reply
              0
              • A Former User? Offline
                A Former User? Offline
                A Former User
                wrote on last edited by
                #8

                What are you talking about? Closed source? The program is an executable that bridges to all 4 games and finds your paths for you and saves everything in an INI so you can use it like an INTERFACE. Why the hell would you want to use command prompts and archaeic methods when I made a program that give Plutonium a nice UI and interface. Lol That doesn't make a lot of sense to be so paranoid aabout malware. I created this using Python and Windows 10 then it is packaged using Windows 10. I will make a Windows 7 / 8 version is there's request for it. Anywho do what you will. Test before you judge ๐Ÿ˜‰

                1 Reply Last reply
                0
                • A Former User? Offline
                  A Former User? Offline
                  A Former User
                  wrote on last edited by
                  #9

                  Here's the source code for PlutoniumX so you can verify the programs safety ๐Ÿ˜‰ import tkinter as tk
                  from tkinter import messagebox
                  from PIL import Image, ImageTk
                  import subprocess
                  import os
                  from pathlib import Path
                  import configparser
                  import threading
                  from typing import Dict, List, Optional, Tuple

                  TITLE = "PlutoniumX"
                  BOOTSTRAPPER = "plutonium-bootstrapper-win32.exe"
                  INI_PATH = "PlutoniumX.ini"
                  GAME_ICONS = {
                  "World at War": "waw.png",
                  "Black Ops 1": "bo1.png",
                  "Black Ops 2": "bo2.png",
                  "Modern Warfare 3": "mw3.png"
                  }

                  ======================================================

                  GAME DEFINITIONS - EACH GAME HAS ITS OWN ISOLATED LOGIC

                  ======================================================

                  GAME_DEFS: Dict[str, Dict[str, object]] = {
                  "waw": {
                  "title": "World at War",
                  "mode_id": "t4mp",
                  "folder_markers": ["main/iw_00.iwd"],
                  "exe_markers": ["CoDWaW.exe", "codwaw.exe"],
                  "storage_markers": ["storage/t4", "storage/pluto_t4_full_game"],
                  "name_tokens": ["waw", "world", "war", "t4", "codwaw"],
                  "anti_tokens": ["black ops", "bo1", "bo2", "t5", "t6", "mw3", "iw5"],
                  "missing_title": "Missing WAW",
                  "missing_text": "Could not find a valid World at War game root under this Plutonium folder tree."
                  },
                  "bo1": {
                  "title": "Black Ops 1",
                  "mode_id": "t5mp",
                  "folder_markers": ["main/iw_00.iwd"],
                  "exe_markers": ["BlackOps.exe", "BlackOpsMP.exe"],
                  "storage_markers": ["storage/t5", "storage/pluto_t5_full_game"],
                  "name_tokens": ["bo1", "black ops", "blackops", "t5", "codbo"],
                  "anti_tokens": ["world at war", "waw", "t4", "bo2", "t6", "mw3", "iw5"],
                  "missing_title": "Missing BO1",
                  "missing_text": "Could not find a valid Black Ops 1 game root under this Plutonium folder tree."
                  },
                  "bo2": {
                  "title": "Black Ops 2",
                  "mode_id": "t6mp",
                  "folder_markers": ["zone/all/base.ipak"],
                  "exe_markers": ["t6mp.exe", "BlackOps2.exe"],
                  "storage_markers": ["storage/t6"],
                  "name_tokens": ["bo2", "black ops ii", "black ops 2", "blackops2", "t6"],
                  "anti_tokens": ["world at war", "waw", "t4", "bo1", "t5", "mw3", "iw5"],
                  "missing_title": "Missing BO2",
                  "missing_text": "Could not find a valid Black Ops II game root under this Plutonium folder tree."
                  },
                  "mw3": {
                  "title": "Modern Warfare 3",
                  "mode_id": "iw5mp",
                  "folder_markers": ["main/iw_00.iwd"],
                  "exe_markers": ["iw5mp.exe", "iw5sp.exe"],
                  "storage_markers": ["storage/iw5"],
                  "name_tokens": ["mw3", "modern warfare 3", "modernwarfare3", "iw5"],
                  "anti_tokens": ["world at war", "waw", "t4", "bo1", "t5", "bo2", "t6"],
                  "missing_title": "Missing MW3",
                  "missing_text": "Could not find a valid Modern Warfare 3 game root under this Plutonium folder tree."
                  }
                  }

                  ======================================================

                  CONFIG HELPERS

                  ======================================================

                  def load_config() -> configparser.ConfigParser:
                  config = configparser.ConfigParser()
                  if os.path.exists(INI_PATH):
                  config.read(INI_PATH)
                  return config

                  def save_config(config: configparser.ConfigParser) -> None:
                  with open(INI_PATH, "w", encoding="utf-8") as f:
                  config.write(f)

                  def get_saved_value(key: str) -> str:
                  config = load_config()
                  return config.get("Paths", key, fallback="").strip()

                  def get_saved_path(key: str) -> Optional[Path]:
                  value = get_saved_value(key)
                  if not value:
                  return None
                  try:
                  return Path(value)
                  except Exception:
                  return None

                  def save_username() -> None:
                  username = username_entry.get().strip()
                  if not username:
                  return
                  config = load_config()
                  if "Paths" not in config:
                  config["Paths"] = {}
                  config["Paths"]["username"] = username
                  save_config(config)

                  def save_detected_paths(launcher_path: Path, game_key: str, game_folder: Path, username: str) -> None:
                  config = load_config()
                  if "Paths" not in config:
                  config["Paths"] = {}
                  config["Paths"]["launcher"] = str(launcher_path)
                  config["Paths"][game_key] = str(game_folder)
                  config["Paths"]["username"] = username
                  save_config(config)

                  ======================================================

                  PATH / VALIDATION HELPERS

                  ======================================================

                  def safe_is_file(path: Path) -> bool:
                  try:
                  return path.is_file()
                  except Exception:
                  return False

                  def safe_is_dir(path: Path) -> bool:
                  try:
                  return path.is_dir()
                  except Exception:
                  return False

                  def has_rel_file(folder: Path, relpath: str) -> bool:
                  try:
                  return (folder / relpath).is_file()
                  except Exception:
                  return False

                  def get_root_dir() -> Path:
                  return Path(file).resolve().parent

                  def find_bootstrapper() -> Optional[Path]:
                  root_dir = get_root_dir()
                  candidates = [
                  root_dir / "bin" / BOOTSTRAPPER,
                  root_dir / BOOTSTRAPPER,
                  ]

                  saved = get_saved_path("launcher")
                  if saved:
                      candidates.insert(0, saved)
                  
                  for candidate in candidates:
                      if candidate and safe_is_file(candidate):
                          return candidate
                  
                  for current_root, dirs, files in os.walk(root_dir):
                      if BOOTSTRAPPER in files:
                          found = Path(current_root) / BOOTSTRAPPER
                          if found.name.lower() == BOOTSTRAPPER.lower():
                              return found
                  
                  return None
                  

                  def game_root_is_valid(game_key: str, folder: Path) -> bool:
                  if not folder or not safe_is_dir(folder):
                  return False

                  game_def = GAME_DEFS[game_key]
                  folder_markers: List[str] = game_def["folder_markers"]  # type: ignore[assignment]
                  exe_markers: List[str] = game_def["exe_markers"]  # type: ignore[assignment]
                  
                  if not any(has_rel_file(folder, marker) for marker in folder_markers):
                      return False
                  
                  if not any(has_rel_file(folder, exe) for exe in exe_markers):
                      return False
                  
                  return True
                  

                  def cached_game_path_is_valid(game_key: str) -> Optional[Path]:
                  saved = get_saved_path(game_key)
                  if saved and game_root_is_valid(game_key, saved):
                  return saved
                  return None

                  def score_candidate(game_key: str, folder: Path) -> int:
                  game_def = GAME_DEFS[game_key]
                  exe_markers: List[str] = game_def["exe_markers"] # type: ignore[assignment]
                  folder_markers: List[str] = game_def["folder_markers"] # type: ignore[assignment]
                  name_tokens: List[str] = game_def["name_tokens"] # type: ignore[assignment]
                  anti_tokens: List[str] = game_def["anti_tokens"] # type: ignore[assignment]

                  score = 0
                  path_lower = str(folder).lower().replace("_", " ").replace("-", " ")
                  folder_name = folder.name.lower().replace("_", " ").replace("-", " ")
                  
                  for marker in folder_markers:
                      if has_rel_file(folder, marker):
                          score += 250
                  
                  for exe in exe_markers:
                      if has_rel_file(folder, exe):
                          score += 400
                  
                  for token in name_tokens:
                      if token in folder_name:
                          score += 150
                      elif token in path_lower:
                          score += 60
                  
                  for bad in anti_tokens:
                      if bad in folder_name:
                          score -= 180
                      elif bad in path_lower:
                          score -= 70
                  
                  # Strong separation rules for the shared iw_00.iwd games.
                  if game_key == "waw":
                      if has_rel_file(folder, "BlackOps.exe") or has_rel_file(folder, "BlackOpsMP.exe"):
                          score -= 500
                      if has_rel_file(folder, "iw5mp.exe"):
                          score -= 500
                      if has_rel_file(folder, "zone/all/base.ipak"):
                          score -= 800
                  elif game_key == "bo1":
                      if has_rel_file(folder, "CoDWaW.exe") or has_rel_file(folder, "codwaw.exe"):
                          score -= 500
                      if has_rel_file(folder, "iw5mp.exe"):
                          score -= 500
                      if has_rel_file(folder, "zone/all/base.ipak"):
                          score -= 800
                  elif game_key == "mw3":
                      if has_rel_file(folder, "CoDWaW.exe") or has_rel_file(folder, "codwaw.exe"):
                          score -= 500
                      if has_rel_file(folder, "BlackOps.exe") or has_rel_file(folder, "BlackOpsMP.exe"):
                          score -= 500
                      if has_rel_file(folder, "zone/all/base.ipak"):
                          score -= 800
                  elif game_key == "bo2":
                      if has_rel_file(folder, "main/iw_00.iwd"):
                          score -= 800
                  
                  depth = len(folder.parts)
                  score -= depth
                  
                  return score
                  

                  ======================================================

                  SCANNING HELPERS

                  ======================================================

                  def collect_scan_roots() -> List[Path]:
                  root_dir = get_root_dir()
                  roots: List[Path] = [root_dir]

                  # Scan the entire Plutonium folder tree first and optionally nearby sibling folders.
                  parent_dir = root_dir.parent
                  if safe_is_dir(parent_dir):
                      roots.append(parent_dir)
                  
                  unique: List[Path] = []
                  seen = set()
                  for root in roots:
                      try:
                          resolved = str(root.resolve())
                      except Exception:
                          resolved = str(root)
                      if resolved in seen:
                          continue
                      seen.add(resolved)
                      unique.append(root)
                  return unique
                  

                  def iter_candidate_folders(scan_roots: List[Path]):
                  seen = set()
                  for base in scan_roots:
                  if not safe_is_dir(base):
                  continue

                      try:
                          base_resolved = str(base.resolve())
                      except Exception:
                          base_resolved = str(base)
                  
                      if base_resolved not in seen:
                          seen.add(base_resolved)
                          yield base
                  
                      for current_root, dirs, files in os.walk(base):
                          folder = Path(current_root)
                          try:
                              resolved = str(folder.resolve())
                          except Exception:
                              resolved = str(folder)
                          if resolved in seen:
                              continue
                          seen.add(resolved)
                          yield folder
                  

                  def find_game_folder(game_key: str, status_var: Optional[tk.StringVar] = None) -> Optional[Path]:
                  cached = cached_game_path_is_valid(game_key)
                  if cached:
                  return cached

                  game_def = GAME_DEFS[game_key]
                  title = str(game_def["title"])
                  scan_roots = collect_scan_roots()
                  best_match: Optional[Tuple[int, Path]] = None
                  checked = 0
                  
                  for folder in iter_candidate_folders(scan_roots):
                      checked += 1
                      if status_var and checked % 75 == 0:
                          status_var.set(f"Scanning {title}... checked {checked} folders")
                          root.update_idletasks()
                  
                      if game_root_is_valid(game_key, folder):
                          score = score_candidate(game_key, folder)
                          if best_match is None or score > best_match[0]:
                              best_match = (score, folder)
                  
                  return best_match[1] if best_match else None
                  

                  ======================================================

                  UI HELPERS

                  ======================================================

                  def show_scanning_popup(status_var: tk.StringVar) -> tk.Toplevel:
                  popup = tk.Toplevel(root)
                  popup.title("Scanner")
                  popup.geometry("360x80")
                  popup.configure(bg="black")
                  popup.resizable(False, False)
                  popup.attributes("-topmost", True)
                  popup.grab_set()

                  popup.update_idletasks()
                  x = (popup.winfo_screenwidth() // 2) - 180
                  y = (popup.winfo_screenheight() // 2) - 40
                  popup.geometry(f"+{x}+{y}")
                  
                  label = tk.Label(
                      popup,
                      textvariable=status_var,
                      font=("Segoe UI", 11),
                      fg="lime",
                      bg="black",
                      wraplength=330,
                      justify="center"
                  )
                  label.pack(expand=True, fill="both", padx=10, pady=10)
                  return popup
                  

                  def set_button_state(enabled: bool) -> None:
                  state = tk.NORMAL if enabled else tk.DISABLED
                  for button in launch_buttons:
                  button.config(state=state)
                  exit_btn.config(state=state)

                  ======================================================

                  LAUNCH FLOW

                  ======================================================

                  def build_launch_command(launcher_path: Path, mode_id: str, game_folder: Path, username: str) -> List[str]:
                  return [
                  str(launcher_path),
                  mode_id,
                  str(game_folder),
                  "+name",
                  username,
                  "-lan",
                  ]

                  def run_launch_flow(game_key: str) -> None:
                  username = username_entry.get().strip()
                  if not username:
                  messagebox.showerror("Username Required", "Please enter a username.")
                  return

                  save_username()
                  set_button_state(False)
                  
                  status = tk.StringVar(value="Initializing scan...")
                  popup = show_scanning_popup(status)
                  
                  def worker() -> None:
                      game_def = GAME_DEFS[game_key]
                      try:
                          status.set("Locating Plutonium bootstrapper...")
                          launcher_path = find_bootstrapper()
                          if not launcher_path:
                              raise RuntimeError(f"Could not find {BOOTSTRAPPER} inside this Plutonium folder.")
                  
                          status.set(f"Checking cached {game_def['title']} path...")
                          game_folder = cached_game_path_is_valid(game_key)
                          if not game_folder:
                              status.set(f"Scanning for {game_def['title']} game root...")
                              game_folder = find_game_folder(game_key, status)
                  
                          if not game_folder:
                              raise RuntimeError(str(game_def["missing_text"]))
                  
                          status.set(f"Saving detected {game_def['title']} path...")
                          save_detected_paths(launcher_path, game_key, game_folder, username)
                  
                          command = build_launch_command(launcher_path, str(game_def["mode_id"]), game_folder, username)
                  
                          status.set(f"Launching {game_def['title']}...")
                          subprocess.Popen(command, cwd=str(launcher_path.parent.parent))
                  
                          def on_success() -> None:
                              try:
                                  popup.destroy()
                              except Exception:
                                  pass
                              set_button_state(True)
                  
                          root.after(0, on_success)
                  
                      except Exception as e:
                          def on_error() -> None:
                              try:
                                  popup.destroy()
                              except Exception:
                                  pass
                              set_button_state(True)
                              messagebox.showerror("Launch Failed", str(e))
                  
                          root.after(0, on_error)
                  
                  threading.Thread(target=worker, daemon=True).start()
                  

                  def launch_waw_smart() -> None:
                  run_launch_flow("waw")

                  def launch_bo1_smart() -> None:
                  run_launch_flow("bo1")

                  def launch_bo2_smart() -> None:
                  run_launch_flow("bo2")

                  def launch_mw3_smart() -> None:
                  run_launch_flow("mw3")

                  ======================================================

                  UI

                  ======================================================

                  root = tk.Tk()
                  root.title(TITLE)
                  root.configure(bg="black")
                  root.geometry("640x640")
                  root.resizable(True, True)

                  logo_frame = tk.Frame(root, bg="black")
                  logo_frame.pack(pady=20)

                  try:
                  logo_img = Image.open("PlutoniumXlogo.png").resize((400, 88))
                  logo_tk = ImageTk.PhotoImage(logo_img)
                  logo_label = tk.Label(logo_frame, image=logo_tk, bg="black")
                  logo_label.image = logo_tk
                  logo_label.pack(padx=20, anchor="center")
                  except Exception:
                  logo_label = tk.Label(logo_frame, text=TITLE, font=("Segoe UI", 28, "bold"), fg="white", bg="black")
                  logo_label.pack(padx=20, anchor="center")

                  username_frame = tk.Frame(root, bg="black")
                  username_frame.pack(pady=10)
                  tk.Label(username_frame, text="Username:", font=("Segoe UI", 12), fg="white", bg="black").pack(side="left")
                  username_entry = tk.Entry(username_frame, font=("Segoe UI", 12), width=24)
                  username_entry.pack(side="left", padx=10)

                  saved_username = get_saved_value("username")
                  if saved_username:
                  username_entry.insert(0, saved_username)

                  def on_enter(event):
                  if event.widget.cget("state") != tk.DISABLED:
                  event.widget.config(bg="white", fg="black")

                  def on_leave(event):
                  if event.widget.cget("state") != tk.DISABLED:
                  event.widget.config(bg="gray20", fg="white")

                  launch_buttons: List[tk.Button] = []

                  for game in GAME_ICONS:
                  frame = tk.Frame(root, bg="black")
                  frame.pack(pady=12)

                  icon_path = GAME_ICONS.get(game, "")
                  try:
                      img = Image.open(icon_path).resize((64, 64))
                      icon = ImageTk.PhotoImage(img)
                      icon_label = tk.Label(frame, image=icon, bg="black")
                      icon_label.image = icon
                      icon_label.pack(side="left", padx=10)
                  except Exception:
                      icon_label = tk.Label(frame, text="[IMG]", bg="black", fg="white", width=10)
                      icon_label.pack(side="left")
                  
                  command = (
                      launch_mw3_smart if game == "Modern Warfare 3"
                      else launch_waw_smart if game == "World at War"
                      else launch_bo1_smart if game == "Black Ops 1"
                      else launch_bo2_smart
                  )
                  
                  btn = tk.Button(
                      frame,
                      text=f"Launch {game}",
                      font=("Segoe UI", 12),
                      bg="gray20",
                      fg="white",
                      activebackground="white",
                      activeforeground="black",
                      width=30,
                      command=command,
                  )
                  btn.pack(side="left")
                  btn.bind("<Enter>", on_enter)
                  btn.bind("<Leave>", on_leave)
                  launch_buttons.append(btn)
                  

                  exit_btn = tk.Button(
                  root,
                  text="Exit",
                  font=("Segoe UI", 12),
                  bg="gray20",
                  fg="white",
                  activebackground="white",
                  activeforeground="black",
                  width=20,
                  command=lambda: [save_username(), root.quit()],
                  )
                  exit_btn.pack(pady=20)
                  exit_btn.bind("<Enter>", on_enter)
                  exit_btn.bind("<Leave>", on_leave)

                  root.mainloop()

                  1 Reply Last reply
                  0
                  • DrSkum88 Offline
                    DrSkum88 Offline
                    DrSkum88
                    wrote on last edited by
                    #10

                    Bro you don't even know how to use git, your vibe coded UI is pointless because it doesn't add anything, it doesn't even look nice, and all your posts read like you scam senior citizens for a living.

                    1 Reply Last reply
                    0
                    • A Former User? Offline
                      A Former User? Offline
                      A Former User
                      wrote on last edited by
                      #11

                      DrSkum lol Dude wtf is your problem man? Grow up 007 ๐Ÿ˜‰ Why are you criticizing a bunch of bullshit that makes no sense. Maybe I don't want to use GIT and I don't need to use that because I don't make a lot of projects to justify using that Seriously there's no need to act like a d#ck and attack me for sharing something that's just an alternative to the lan launcher BTW This thread can be closed out and deleted im making a new thread with the Final version now with better features as well

                      1 Reply Last reply
                      0

                      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                      With your input, this post could be even better ๐Ÿ’—

                      Register Login
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Unread 0
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Donate