Advertisement
Guest User

Oblivion Launcher Python Source

a guest
Apr 26th, 2025
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.74 KB | None | 0 0
  1. import subprocess
  2. import os
  3. import sys
  4. import threading
  5. import time
  6. import ctypes
  7. import shutil
  8. import win32com.client
  9.  
  10. import pystray
  11. from PIL import Image
  12.  
  13. import win32gui
  14. import win32con
  15.  
  16. def hide_console():
  17.     """Hides the console window (Windows only)."""
  18.     ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)
  19.  
  20. def resource_path(relative_path):
  21.     """ Get absolute path to resource, works for dev and PyInstaller """
  22.     try:
  23.         base_path = sys._MEIPASS
  24.         print(f"Running in PyInstaller, base path: {base_path}") # Add this
  25.     except AttributeError:
  26.         base_path = os.path.abspath(".")
  27.         print(f"Running outside PyInstaller, base path: {base_path}")
  28.  
  29.     return os.path.join(base_path, relative_path)
  30.  
  31. def save_profile(monitor_switcher, profiles_dir, filename, profile_type):
  32.     """Saves the current monitor setup to the given filename."""
  33.     profile_path = os.path.join(profiles_dir, filename)
  34.     subprocess.run(
  35.         [monitor_switcher, f'-save:{profile_path}'],
  36.         check=True,
  37.         creationflags=subprocess.CREATE_NO_WINDOW
  38.     )
  39.     # Show confirmation popup
  40.     ctypes.windll.user32.MessageBoxW(
  41.         0,
  42.         f"{profile_type} Profile saved successfully!",
  43.         "Oblivion Launcher",
  44.         0
  45.     )
  46.  
  47. def apply_profile(monitor_switcher, profile_path):
  48.     """Applies the given monitor profile."""
  49.     subprocess.run(
  50.         [monitor_switcher, f'-load:{profile_path}'],
  51.         check=True,
  52.         creationflags=subprocess.CREATE_NO_WINDOW
  53.     )
  54.  
  55. def close_warning_window():
  56.     """Searches for and closes the specific warning window."""
  57.     warning_title = "Thank you for installing TESIV: Oblivion (Remastered)"
  58.  
  59.     for _ in range(30):  # Try for 30 seconds
  60.         hwnd = win32gui.FindWindow(None, warning_title)
  61.         if hwnd:
  62.             print("Warning window detected. Closing it...")
  63.             win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
  64.             return
  65.         time.sleep(1)
  66.        
  67. def check_game_exe(launcher_dir):
  68.     """Checks if OblivionRemastered.exe exists and shows a popup if not."""
  69.     game_exe = os.path.join(launcher_dir, "OblivionRemastered.exe")
  70.     if not os.path.exists(game_exe):
  71.         # Display the message box
  72.         ctypes.windll.user32.MessageBoxW(
  73.             0,
  74.             "Game executable not found.\n\n"
  75.             "Please ensure the Launcher is in the Oblivion Remastered game directory with the 'OblivionRemastered.exe' file.",
  76.             "Oblivion Launcher",
  77.             0  # MB_OK style for a simple OK button
  78.         )
  79.         sys.exit(0)  # Exit the program if the OK button is clicked
  80.  
  81. def check_profiles(profiles_dir, launcher_path):
  82.     """Checks if the necessary profiles exist. If not, show instructions."""
  83.     game_profile = os.path.join(profiles_dir, "Game.xml")
  84.     default_profile = os.path.join(profiles_dir, "Default.xml")
  85.    
  86.     if not os.path.exists(game_profile) or not os.path.exists(default_profile):
  87.         # Create shortcuts for setting the profiles
  88.         create_shortcut(launcher_path, "-set-default", "Launcher - Set Default Profile.lnk")
  89.         create_shortcut(launcher_path, "-set-game", "Launcher - Set Game Profile.lnk")
  90.         # Show tips message
  91.         message = (
  92.             "Monitor Profiles Not Found \n\n"
  93.             "Please use the newly created shortcuts to configure your profiles.\n\n"
  94.             "How to Use:\n"
  95.             "When you run one of the shortcuts, it will save your current Monitor Configuration settings for the corresponding mode.\n\n"
  96.             "- Run 'Launcher - Set Default Profile' while you are in your main monitor configuration that you regularly use.\n\n"
  97.             "- Run 'Launcher - Set Game Profile' while you are in a monitor configuration that you know works for the game.\n\n"
  98.             "The Launcher will change your display settings to your Game configuration while you're playing, and automatically change it back when you close the game. It will also automatically close the warning you get if you do not meet the minimum specifications."
  99.         )
  100.         ctypes.windll.user32.MessageBoxW(
  101.             0,
  102.             message,
  103.             "Oblivion Launcher",
  104.             0
  105.         )
  106.        
  107.         sys.exit(0)
  108.  
  109. def create_shortcut(target_path, arguments, shortcut_name):
  110.     """Creates a shortcut with the given target and arguments."""
  111.     shell = win32com.client.Dispatch('WScript.Shell')
  112.     desktop = os.path.dirname(os.path.abspath(target_path))  # Directory of the launcher
  113.     shortcut_path = os.path.join(desktop, shortcut_name)
  114.    
  115.     shortcut = shell.CreateShortCut(shortcut_path)
  116.     shortcut.TargetPath = target_path
  117.     shortcut.Arguments = arguments
  118.     shortcut.IconLocation = target_path  # You can use an icon for the shortcut
  119.     shortcut.save()
  120.  
  121. def main():
  122.     # Hide the console immediately
  123.     hide_console()
  124.  
  125.     # Get the directory where the launcher script is located
  126.     launcher_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
  127.    
  128.     check_game_exe(launcher_dir)
  129.  
  130.     # Make sure necessary folders exist
  131.     os.makedirs(os.path.join(launcher_dir, ".Launcher"), exist_ok=True)
  132.  
  133.     # Paths
  134.     monitor_switcher = resource_path("MonitorSwitcher.exe")
  135.     profiles_dir = os.path.join(launcher_dir, ".Launcher")
  136.     game_exe = os.path.join(launcher_dir, "OblivionRemastered.exe")
  137.     icon_path = resource_path("icon.ico")
  138.  
  139.     # Handle CLI arguments
  140.     if len(sys.argv) > 1:
  141.         arg = sys.argv[1].lower()
  142.  
  143.         try:
  144.             if arg == "-set-default":
  145.                 save_profile(monitor_switcher, profiles_dir, "Default.xml", "Default")
  146.             elif arg == "-set-game":
  147.                 save_profile(monitor_switcher, profiles_dir, "Game.xml", "Game")
  148.             else:
  149.                 ctypes.windll.user32.MessageBoxW(
  150.                     0,
  151.                     f"Unknown argument: {arg}",
  152.                     "Error",
  153.                     0
  154.                 )
  155.         except subprocess.CalledProcessError as e:
  156.             ctypes.windll.user32.MessageBoxW(
  157.                 0,
  158.                 f"Error saving monitor profile:\n{str(e)}",
  159.                 "Error",
  160.                 0
  161.             )
  162.  
  163.         sys.exit(0)
  164.        
  165.     # Check if profiles exist
  166.     check_profiles(profiles_dir, os.path.join(launcher_dir, "Oblivion Launcher.exe"))
  167.  
  168.     # Setup system tray icon
  169.     icon_image = Image.open(icon_path)
  170.     icon = pystray.Icon("OblivionRemastered", icon_image, "Oblivion is running...", menu=None)
  171.  
  172.     def run_icon():
  173.         icon.run()
  174.  
  175.     try:
  176.         # Apply the Game monitor profile
  177.         game_profile = os.path.join(profiles_dir, "Game.xml")
  178.         default_profile = os.path.join(profiles_dir, "Default.xml")
  179.         apply_profile(monitor_switcher, game_profile)
  180.  
  181.         # Launch the game
  182.         game_proc = subprocess.Popen([game_exe])
  183.  
  184.         # Start the tray icon in a separate thread
  185.         tray_thread = threading.Thread(target=run_icon, daemon=True)
  186.         tray_thread.start()
  187.  
  188.         # Start a thread to close the warning window
  189.         warning_thread = threading.Thread(target=close_warning_window, daemon=True)
  190.         warning_thread.start()
  191.  
  192.         # Wait for the game to close
  193.         game_proc.wait()
  194.  
  195.     except subprocess.CalledProcessError as e:
  196.         print(f"Error applying monitor profile: {e}")
  197.     except FileNotFoundError as e:
  198.         print(f"Error launching application: {e}")
  199.     finally:
  200.         # Reapply the Default monitor profile
  201.         try:
  202.             apply_profile(monitor_switcher, default_profile)
  203.         except subprocess.CalledProcessError as e:
  204.             print(f"Error reverting to default profile: {e}")
  205.         finally:
  206.             icon.stop()
  207.  
  208. if __name__ == "__main__":
  209.     main()
  210.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement