Example #1
0
    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()))
Example #2
0
    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))
Example #3
0
    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()
Example #4
0
 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")
Example #5
0
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)