def _process_interacted(self): if gsi_handlers.sim_info_culling_handler.is_archive_enabled(): gsi_archive = CullingArchive('Interacted Pass') gsi_archive.census_before = self._get_gsi_culling_census() else: gsi_archive = None culling_service = services.get_culling_service() cap = self._get_cap_level(SimInfoLODLevel.INTERACTED) sim_info_manager = services.sim_info_manager() interacted_sim_ids_in_priority_order = culling_service.get_interacted_sim_ids_in_priority_order() interacted_count = 0 for sim_id in interacted_sim_ids_in_priority_order: sim_info = sim_info_manager.get(sim_id) if sim_info is None or sim_info.lod != SimInfoLODLevel.INTERACTED: culling_service.remove_sim_from_interacted_sims(sim_id) else: interacted_count += 1 if cap < interacted_count: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=interacted_sim_ids_in_priority_order.index(sim_id), info='last interaction too old') if sim_info.request_lod(SimInfoLODLevel.BASE): culling_service.remove_sim_from_interacted_sims(sim_id) interacted_count -= 1 if gsi_archive is not None: gsi_archive.add_sim_info_action(sim_info, action='drop to BASE') elif gsi_archive is not None: gsi_archive.add_sim_info_action(sim_info, action='failed to drop to INTERACTED') elif gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=interacted_sim_ids_in_priority_order.index(sim_id), info='no pressure to drop') if gsi_archive is not None: gsi_archive.census_after = self._get_gsi_culling_census() gsi_archive.apply()
def cull_household(household_id: OptionalHouseholdParam, _connection=None): culling_service = services.get_culling_service() if culling_service is None: return household = get_optional_target(household_id, target_type=OptionalHouseholdParam, _connection=_connection) if household is None: return False culling_service.cull_household(household, is_important_fn=lambda _: False) return True
def print_culling_scores(_connection=None): sim_info_manager = services.sim_info_manager() if sim_info_manager is None: return False culling_service = services.get_culling_service() if culling_service is None: return False output = Output(_connection) sim_infos = sim_info_manager.get_sim_infos_with_lod(SimInfoLODLevel.BASE) for sim_info in sim_infos: culling_service.get_culling_score_for_sim_info(sim_info, output=output) return True
def __call__(self): culling_service = services.get_culling_service() max_player_population = culling_service.get_max_player_population() if max_player_population: household_manager = services.household_manager() player_population = sum( len(household) for household in household_manager.values() if household.is_player_household) if player_population >= max_player_population: return TestResult( False, 'Over the maximum player population ({}/{})', player_population, max_player_population, tooltip=lambda *_, **__: self.tooltip( player_population, max_player_population)) return TestResult.TRUE
def set_max_player_population(max_player_population: int = 0, _connection=None): culling_service = services.get_culling_service() culling_service.set_max_player_population(max_player_population) return True
def _process_background(self): culling_service = services.get_culling_service() if gsi_handlers.sim_info_culling_handler.is_archive_enabled(): gsi_archive = CullingArchive('Background Pass') gsi_archive.census_before = self._get_gsi_culling_census() else: gsi_archive = None background_cap = self._get_cap_level(SimInfoLODLevel.BACKGROUND) sim_info_manager = services.sim_info_manager() sim_infos = sim_info_manager.get_sim_infos_with_lod(SimInfoLODLevel.BACKGROUND) households = frozenset(sim_info.household for sim_info in sim_infos) num_infos_above_background_lod = sim_info_manager.get_num_sim_infos_with_criteria(lambda sim_info: sim_info.lod > SimInfoLODLevel.BACKGROUND) full_and_active_cap = self._get_cap_level(SimInfoLODLevel.FULL) + Household.MAXIMUM_SIZE cap_overage = num_infos_above_background_lod - full_and_active_cap cap = max(background_cap - cap_overage, 0) if cap_overage > 0 else background_cap sim_info_immunity_reasons = {} sim_info_scores = {} for sim_info in sim_infos: immunity_reasons = sim_info.get_culling_immunity_reasons() if immunity_reasons: sim_info_immunity_reasons[sim_info] = immunity_reasons else: sim_info_scores[sim_info] = culling_service.get_culling_score_for_sim_info(sim_info) household_scores = {} immune_households = set() for household in households: if any(sim_info.lod != SimInfoLODLevel.BACKGROUND or sim_info in sim_info_immunity_reasons for sim_info in household): immune_households.add(household) else: score = max(sim_info_scores[sim_info].score for sim_info in household) household_scores[household] = score if gsi_archive is not None: for (sim_info, immunity_reasons) in sim_info_immunity_reasons.items(): gsi_archive.add_sim_info_cullability(sim_info, info='immune: {}'.format(', '.join(reason.gsi_reason for reason in immunity_reasons))) for (sim_info, score) in sim_info_scores.items(): gsi_archive.add_sim_info_cullability(sim_info, score=score.score, rel_score=score.rel_score, inst_score=score.inst_score, importance_score=score.importance_score) def get_sim_cullability(sim_info): if sim_info.lod > SimInfoLODLevel.BACKGROUND: return 'LOD is not BACKGROUND' if sim_info in sim_info_immunity_reasons: return ', '.join(reason.gsi_reason for reason in sim_info_immunity_reasons[sim_info]) elif sim_info in sim_info_scores: return str(sim_info_scores[sim_info].score) return '' for household in immune_households: member_cullabilities = ', '.join('{} ({})'.format(sim_info.full_name, get_sim_cullability(sim_info)) for sim_info in household) gsi_archive.add_household_cullability(household, info='immune: {}'.format(member_cullabilities)) for (household, score) in household_scores.items(): member_cullabilities = ', '.join('{} ({})'.format(sim_info.full_name, get_sim_cullability(sim_info)) for sim_info in household) gsi_archive.add_household_cullability(household, score=score, info=member_cullabilities) self._precull_telemetry_data['imho'] = len(immune_households) self._precull_telemetry_data['imsi'] = len(sim_info_immunity_reasons) self._precull_telemetry_data['imsc'] = sum(len(h) for h in immune_households) self._precull_telemetry_data.update(reason.telemetry_hook for reason in itertools.chain.from_iterable(sim_info_immunity_reasons.values())) for reason in CullingReasons.ALL_CULLING_REASONS: if reason not in self._precull_telemetry_data: self._precull_telemetry_data[reason.telemetry_hook] = 0 culling_service = services.get_culling_service() sorted_households = sorted(household_scores, key=household_scores.get) num_to_cull = self._get_num_to_cull(len(sim_infos), cap) while sorted_households: while num_to_cull > 0: household = sorted_households.pop(0) num_to_cull -= len(household) culling_service.cull_household(household, is_important_fn=self._has_player_sim_in_family_tree, gsi_archive=gsi_archive) for sim_info in sim_info_manager.get_all(): if sim_info.household is None: logger.error('Found sim info {} without household during sim culling.', sim_info) if gsi_archive is not None: gsi_archive.census_after = self._get_gsi_culling_census() gsi_archive.apply()
def _process_full(self): if gsi_handlers.sim_info_culling_handler.is_archive_enabled(): gsi_archive = CullingArchive('Full Pass') gsi_archive.census_before = self._get_gsi_culling_census() else: gsi_archive = None cap = self._get_cap_level(SimInfoLODLevel.FULL) sim_infos = services.sim_info_manager().get_sim_infos_with_lod(SimInfoLODLevel.FULL) now = services.time_service().sim_now mandatory_drops = set() scores = {} for sim_info in sim_infos: if sim_info.is_instanced(allow_hidden_flags=ALL_HIDDEN_REASONS): if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- instanced') if not sim_info.is_player_sim: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=0, info='mandatory drop -- non-player') mandatory_drops.add(sim_info) elif sim_info.household.home_zone_id != 0: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- player and not homeless') if self.homeless_played_demotion_time is not None: days_homeless = (now - sim_info.household.home_zone_move_in_time).in_days() if days_homeless < self.homeless_played_demotion_time: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- not homeless long enough') if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=days_homeless, info='homeless for too long') scores[sim_info] = days_homeless else: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=days_homeless, info='homeless for too long') scores[sim_info] = days_homeless if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- no pressure to drop') elif gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- no pressure to drop') elif self.homeless_played_demotion_time is not None: days_homeless = (now - sim_info.household.home_zone_move_in_time).in_days() if days_homeless < self.homeless_played_demotion_time: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- not homeless long enough') if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=days_homeless, info='homeless for too long') scores[sim_info] = days_homeless else: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=days_homeless, info='homeless for too long') scores[sim_info] = days_homeless if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- no pressure to drop') elif gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- no pressure to drop') elif not sim_info.is_player_sim: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=0, info='mandatory drop -- non-player') mandatory_drops.add(sim_info) elif sim_info.household.home_zone_id != 0: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- player and not homeless') if self.homeless_played_demotion_time is not None: days_homeless = (now - sim_info.household.home_zone_move_in_time).in_days() if days_homeless < self.homeless_played_demotion_time: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- not homeless long enough') if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=days_homeless, info='homeless for too long') scores[sim_info] = days_homeless else: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=days_homeless, info='homeless for too long') scores[sim_info] = days_homeless if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- no pressure to drop') elif gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- no pressure to drop') elif self.homeless_played_demotion_time is not None: days_homeless = (now - sim_info.household.home_zone_move_in_time).in_days() if days_homeless < self.homeless_played_demotion_time: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- not homeless long enough') if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=days_homeless, info='homeless for too long') scores[sim_info] = days_homeless else: if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, score=days_homeless, info='homeless for too long') scores[sim_info] = days_homeless if gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- no pressure to drop') elif gsi_archive is not None: gsi_archive.add_sim_info_cullability(sim_info, info='immune -- no pressure to drop') num_to_cull = self._get_num_to_cull(len(sim_infos) - len(mandatory_drops), cap) sorted_sims = sorted(scores.keys(), key=lambda x: scores[x], reverse=True) culling_service = services.get_culling_service() for sim_info in itertools.chain(mandatory_drops, sorted_sims[:num_to_cull]): if culling_service.has_sim_interacted_with_active_sim(sim_info.sim_id): new_lod = SimInfoLODLevel.INTERACTED else: new_lod = SimInfoLODLevel.BASE if sim_info.request_lod(new_lod): if gsi_archive is not None: gsi_archive.add_sim_info_action(sim_info, action='drop to {}'.format(new_lod)) elif gsi_archive is not None: gsi_archive.add_sim_info_action(sim_info, action='failed to drop to {}'.format(new_lod)) if gsi_archive is not None: gsi_archive.census_after = self._get_gsi_culling_census() gsi_archive.apply()