def test_process_scanning(self): process_scanner = processes.ProcessScanner(self.log) process_scanner.executables['posix'].append('python') process_scanner.executables['nt'].append('python') self.assertEqual(len(process_scanner.scan()), 3) p_info = process_scanner.get_process_info(os.getpid(), ('path', 'time')) self.assertEqual(p_info['running'], True) self.assertTrue( 'python' in p_info['path'].lower()) # hope your Python installation is sane self.assertGreater(p_info['time'], 1228305600) # Python 3 release date lol self.assertFalse(process_scanner.hl2_exe_is_tf2(os.getpid()))
def test_discoipc(self): # this test fails if Discord isn't running test_process_scanner = processes.ProcessScanner(self.log) if not test_process_scanner.scan()['Discord']['running']: self.skipTest("Discord needs to be running") activity = { 'details': "Testing TF2 Rich Presence", 'timestamps': { 'start': int(time.time()) }, 'assets': { 'small_image': 'tf2_icon_small', 'small_text': 'Team Fortress 2', 'large_image': 'main_menu', 'large_text': 'In menus' }, 'state': "(Probably don't actually have the game open)" } client = ipc.DiscordIPC('429389143756374017') time.sleep(0.1) # this fix works? seriously? client.connect() client.update_activity(activity) client_state = (client.client_id, client.connected, client.ipc_path, isinstance(client.pid, int), client.platform, isinstance(client.socket, io.BufferedRandom), client.socket.name) self.assertEqual( client_state, ('429389143756374017', True, '\\\\?\\pipe\\discord-ipc-0', True, 'windows', True, '\\\\?\\pipe\\discord-ipc-0')) client.disconnect() client_state = (client.client_id, client.connected, client.ipc_path, isinstance(client.pid, int), client.platform, client.socket) self.assertEqual(client_state, ('429389143756374017', False, '\\\\?\\pipe\\discord-ipc-0', True, 'windows', None))
def __init__(self, log: Optional[logger.Log] = None, set_process_priority: bool = True): if log: self.log: logger.Log = log else: self.log = logger.Log() self.log.error( f"Initialized main.TF2RichPresense without a log, defaulting to one at {self.log.filename}" ) settings.fix_settings(self.log) default_settings: dict = settings.defaults() current_settings: dict = settings.access_registry() if current_settings == default_settings: self.log.debug("Current settings are default") else: self.log.debug( f"Non-default settings: {settings.compare_settings(default_settings, current_settings)}" ) self.gui: gui.GUI = gui.GUI(self.log, main_controlled=True) self.process_scanner: processes.ProcessScanner = processes.ProcessScanner( self.log) self.loc: localization.Localizer = localization.Localizer(self.log) self.game_state: game_state.GameState = game_state.GameState( self.log, self.loc) self.rpc_client: Optional[ipc.DiscordIPC] = None self.client_connected: bool = False self.rpc_connected: bool = False self.test_state: str = 'init' self.activity: dict = {} self.should_mention_discord: bool = True self.should_mention_tf2: bool = True self.should_mention_steam: bool = True self.has_checked_class_configs: bool = False self.has_seen_kataiser: bool = False self.console_log_mtime: Optional[int] = None self.old_console_log_mtime: Optional[int] = None self.loop_iteration: int = 0 self.custom_functions = None self.usernames: Set[str] = set() self.last_name_scan_time: float = time.time() # close enough self.steam_config_mtimes: Dict[str, int] = {} self.cleanup_primed: bool = True self.slow_sleep_time: bool = False self.has_set_process_priority: bool = not set_process_priority self.kataiser_scan_loop: int = 0 self.did_init_operations: bool = False self.no_condebug: bool = False self.fast_next_loop: bool = False self.reset_launched_with_button: bool = False self.last_console_log_size: Optional[int] = None try: self.log.cleanup(20 if launcher.DEBUG else 10) except (FileNotFoundError, PermissionError): self.log.error( f"Couldn't clean up logs folder:\n{traceback.format_exc()}") self.log.debug( f"CPU: {psutil.cpu_count(logical=False)} cores, {psutil.cpu_count()} threads, {round(psutil.cpu_freq().max / 1000, 1)} GHz" ) platform_info: Dict[str, Any] = { 'architecture': platform.architecture, 'machine': platform.machine, 'system': platform.system, 'platform': platform.platform, 'processor': platform.processor, 'python_version_tuple': platform.python_version_tuple } for platform_part in platform_info: try: if platform_part == 'platform': platform_info[platform_part] = platform_info[ platform_part](aliased=True) else: platform_info[platform_part] = platform_info[ platform_part]() except Exception: self.log.error( f"Exception during platform.{platform_part}(), skipping\n{traceback.format_exc()}" ) self.log.debug(f"Platform: {platform_info}") if not os.path.supports_unicode_filenames: self.log.error( "Looks like the OS doesn't support unicode filenames. This might cause problems" ) self.import_custom()
def test_get_steam_username(self): if processes.ProcessScanner(self.log).scan()['Steam']['running']: self.assertNotEqual(configs.get_steam_username(), '') else: self.skipTest("Steam isn't running, assuming it's not installed")
def main(): output_log_txt_path = "{}\\AppData\\LocalLow\\Hopoo Games, LLC\\Risk of Rain 2\\output_log.txt".format(os.getenv('UserProfile')) start_time = int(time.time()) activity = {'details': 'Loading game', # this is what gets modified and sent to Discord via discoIPC 'timestamps': {'start': start_time}, 'assets': {'small_image': ' ', 'small_text': 'Risk of Rain 2', 'large_image': 'logo', 'large_text': 'Risk of Rain 2'}, 'state': 'Not in lobby'} client_connected = False has_mention_not_running = False process_scanner = processes.ProcessScanner() while True: next_delay = 5 p_data = process_scanner.scan() activity['timestamps']['start'] = p_data['ROR2']['time'] if p_data['ROR2']['running'] and p_data['Discord']['running']: if not client_connected: # connects to Discord client = ipc.DiscordIPC('566395208858861569') client.connect() client_connected = True with open(output_log_txt_path, 'r', errors='replace') as output_log_txt: output_log = output_log_txt.readlines() old_details_state = copy.copy((activity['details'], activity['state'])) for line in output_log: if 'Loaded scene' in line: activity = switch_image_mode(activity) if 'title' in line: activity['details'] = "Main menu" activity['state'] = "Not in lobby" elif 'lobby loadSceneMode=Single' in line: activity['details'] = "In lobby" activity['state'] = "Singleplayer" elif 'crystalworld' in line: activity['state'] = "Prismatic Trials" elif 'golemplains' in line: activity = switch_image_mode(activity, ('golemplains', 'Titanic Plains')) elif 'blackbeach' in line: activity = switch_image_mode(activity, ('blackbeach', 'Distant Roost')) elif 'goolake' in line: activity = switch_image_mode(activity, ('goolake', 'Abandoned Aquaduct')) elif 'frozenwall' in line: activity = switch_image_mode(activity, ('frozenwall', 'Rallypoint Delta')) elif 'dampcavesimple' in line: activity = switch_image_mode(activity, ('dampcavesimple', 'Abyssal Depths')) elif 'mysteryspace' in line: activity = switch_image_mode(activity, ('mysteryspace', 'Hidden Realm: A Moment, Fractured')) elif 'bazaar' in line: activity = switch_image_mode(activity, ('bazaar', 'Hidden Realm: Bazaar Between Time')) elif 'foggyswamp' in line: activity = switch_image_mode(activity, ('foggyswamp', 'Wetland Aspect')) elif 'wispgraveyard' in line: activity = switch_image_mode(activity, ('wispgraveyard', 'Scorched Acres')) elif 'goldshores' in line: activity = switch_image_mode(activity, ('goldshores', 'Gilded Coast')) elif 'lobby creation succeeded' in line: activity['details'] = "In lobby" activity['state'] = "Multiplayer" activity = switch_image_mode(activity) elif 'Left lobby' in line: activity['details'] = "Main menu" activity['state'] = "Not in lobby" activity = switch_image_mode(activity) if time.time() - start_time < 10: activity['details'] = "Loading game" if old_details_state != (activity['details'], activity['state']): next_delay = 2 print(activity['details']) print(activity['state']) time_elapsed = time.time() - start_time print("{:02}:{:02} elapsed\n".format(int(time_elapsed / 60), round(time_elapsed % 60))) if not os.path.exists('history.txt'): open('history.txt', 'w').close() activity_str = f'{activity}\n' with open('history.txt', 'r') as history_file_r: history = history_file_r.readlines() if activity_str not in history: with open('history.txt', 'a') as history_file_a: history_file_a.write(activity_str) # send everything to discord client.update_activity(activity) elif not p_data['Discord']['running']: print("{}\nDiscord isn't running\n") else: if client_connected: try: client.disconnect() # doesn't work... except: pass raise SystemExit # ...but this does else: if not has_mention_not_running: print("Risk of Rain 2 isn't running\n") has_mention_not_running = True # to prevent connecting when already connected client_connected = False time.sleep(next_delay)