33import os
44import re
55from pathlib import Path
6- from selenium import webdriver
7- from selenium .webdriver .chrome .options import Options
86
97def get_app_name ():
108 """Get the app name from environment variable, falling back to default"""
@@ -30,20 +28,54 @@ def get_product_name():
3028 # If regex fails, return default
3129 return "SampleApp"
3230
31+ def get_company_name ():
32+ """Get the company name from ProjectSettings.asset (used for log paths on some macOS setups)."""
33+ project_settings_path = Path (__file__ ).resolve ().parent .parent .parent / 'ProjectSettings' / 'ProjectSettings.asset'
34+
35+ if not project_settings_path .exists ():
36+ print (f"Warning: ProjectSettings.asset not found at { project_settings_path } " )
37+ return None
38+
39+ try :
40+ with open (project_settings_path , 'r' ) as f :
41+ content = f .read ()
42+ match = re .search (r'companyName: (.+)' , content )
43+ if match :
44+ return match .group (1 ).strip ()
45+ except Exception as e :
46+ print (f"Warning: failed to read companyName from ProjectSettings.asset: { e } " )
47+ return None
48+
3349def get_logout_url_from_unity_logs ():
3450 """Monitor Unity logs to capture logout URLs."""
3551 import tempfile
52+ from pathlib import Path as _Path
3653
3754 product_name = os .getenv ("UNITY_APP_NAME" , get_product_name ())
55+ company_name = get_company_name ()
3856
3957 # Unity log file locations on macOS
4058 log_paths = [
4159 os .path .join (os .path .expanduser ("~" ), "Library" , "Logs" , "Unity" , product_name , "Player.log" ),
4260 os .path .join (os .path .expanduser ("~" ), "Library" , "Logs" , product_name , "Player.log" ),
61+ # Common standalone player paths
62+ os .path .join (os .path .expanduser ("~" ), "Library" , "Logs" , "Unity" , "Player.log" ),
63+ os .path .join (os .path .expanduser ("~" ), "Library" , "Logs" , "Unity" , product_name , "Player.log" ),
64+ os .path .join (os .path .expanduser ("~" ), "Library" , "Logs" , "Unity" , "Player.log" ),
4365 os .path .join (tempfile .gettempdir (), "UnityPlayer.log" ),
4466 "Player.log" # Current directory
4567 ]
68+
69+ if company_name :
70+ log_paths .insert (
71+ 0 ,
72+ os .path .join (os .path .expanduser ("~" ), "Library" , "Logs" , company_name , product_name , "Player.log" ),
73+ )
4674
75+ # De-dup while preserving order
76+ seen = set ()
77+ log_paths = [p for p in log_paths if not (p in seen or seen .add (p ))]
78+
4779 for log_path in log_paths :
4880 if os .path .exists (log_path ):
4981 print (f"Monitoring Unity log for logout URL: { log_path } " )
@@ -62,27 +94,53 @@ def get_logout_url_from_unity_logs():
6294 except Exception as e :
6395 print (f"Error reading log file { log_path } : { e } " )
6496 continue
97+
98+ # Fallback: scan ~/Library/Logs for any Player.log and try the most recently modified few.
99+ # This helps on standalone runners where Unity logs may be under Company/Product folders.
100+ try :
101+ logs_root = _Path (os .path .expanduser ("~" )) / "Library" / "Logs"
102+ if logs_root .exists ():
103+ candidates = []
104+ for p in logs_root .rglob ("Player.log" ):
105+ try :
106+ candidates .append ((p .stat ().st_mtime , str (p )))
107+ except Exception :
108+ continue
109+
110+ # Newest first; try a small number to avoid slow scans.
111+ candidates .sort (reverse = True )
112+ for _ , p in candidates [:10 ]:
113+ if p in seen :
114+ continue
115+ print (f"Monitoring Unity log for logout URL (fallback): { p } " )
116+ try :
117+ with open (p , 'r' , encoding = 'utf-8' , errors = 'ignore' ) as f :
118+ content = f .read ()
119+ matches = re .findall (r'(?:\[Immutable\] PASSPORT_AUTH_URL: |PASSPORT_AUTH_URL: |LaunchAuthURL : )(https?://[^\s]+)' , content )
120+ if matches :
121+ for url in reversed (matches ):
122+ if 'logout' in url or 'im-logged-out' in url :
123+ print (f"Found logout URL: { url } " )
124+ return url
125+ except Exception as e :
126+ print (f"Error reading log file { p } : { e } " )
127+ continue
128+ except Exception as e :
129+ print (f"Warning: fallback Player.log scan failed: { e } " )
65130
66131 print ("No logout URL found in Unity logs" )
67132 return None
68133
69134def logout_with_controlled_browser ():
70- """Handle logout using the controlled browser instance instead of letting Unity open its own browser."""
135+ """Handle logout without relying on Selenium/ChromeDriver.
136+
137+ The Unity sample app already opens the logout URL in the system browser when LogoutBtn is tapped.
138+ Here we monitor Unity logs to capture that logout URL, extract its `returnTo` deep-link, and
139+ trigger it via `open` so Unity receives the callback deterministically.
140+ """
71141 print ("Starting controlled logout process..." )
72-
73- # Set up Chrome WebDriver options to connect to the existing browser instance
74- chrome_options = Options ()
75- chrome_options .add_experimental_option ("debuggerAddress" , "localhost:9222" )
76-
77- # Brave binary location on macOS
78- brave_path = "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
79- chrome_options .binary_location = brave_path
80-
142+
81143 try :
82- # Connect to the existing browser instance
83- driver = webdriver .Chrome (options = chrome_options )
84- print ("Connected to existing browser for logout" )
85-
86144 # Monitor Unity logs for logout URL
87145 print ("Monitoring Unity logs for logout URL..." )
88146 logout_url = None
@@ -93,17 +151,8 @@ def logout_with_controlled_browser():
93151 time .sleep (1 )
94152
95153 if logout_url :
96- print (f"Navigating controlled browser to logout URL: { logout_url } " )
97- driver .get (logout_url )
98-
99- # Wait for logout page to load
100- time .sleep (3 )
101- print ("Logout completed in controlled browser" )
102-
103- # Check final page
104- current_url = driver .current_url
105- print (f"Final logout URL: { current_url } " )
106-
154+ print (f"Captured logout URL from Unity logs: { logout_url } " )
155+
107156 # Extract the deep-link from the redirect
108157 # Look for immutablerunner://logout in the response or extract from returnTo parameter
109158 if 'returnTo=' in logout_url :
@@ -118,6 +167,10 @@ def logout_with_controlled_browser():
118167 print (f"Triggering deep-link manually: { return_to } " )
119168 subprocess .run (['open' , return_to ], check = False )
120169 time .sleep (2 )
170+ else :
171+ print ("Warning: returnTo parameter present but could not be parsed." )
172+ else :
173+ print ("Warning: logout URL did not include returnTo; cannot trigger deep-link callback." )
121174
122175 else :
123176 print ("Could not find logout URL in Unity logs - logout may complete without browser interaction" )
0 commit comments