NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

repository.py (10394B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\cosmetics\client\character\title\repository\repository.py
      2 import logging
      3 from datetime import datetime, timedelta
      4 from carbon.common.script.sys.serviceConst import ROLE_QA
      5 from character.client.identifier import CharacterIdentifier
      6 from cosmetics.client.character.title.api import signal as api_signal
      7 from cosmetics.client.character.title.const import LOGGER_NAME
      8 from cosmetics.client.character.title.model.definition.identifier import TitleIdentifier
      9 from cosmetics.client.character.title.model.state.owned import CachedOwnedTitles
     10 from cosmetics.client.character.title.model.state.equipped import CachedEquippedTitleAttributes, EquippedTitleStateAttributes
     11 from cosmetics.client.character.title.repository.flatbuffer.repository import TitleLocalizedDefinitionsRepository
     12 from cosmetics.client.character.title.repository.message_bus.request_messenger import TitleRequestMessenger
     13 from cosmetics.client.character.title.repository.message_bus.notice_listener import TitleNoticeListener
     14 from cosmetics.client.character.title.repository.message_bus import notice_listener_signal
     15 from featuremanagement.client.flag import flag_bool
     16 from localization.util import GetLanguageID
     17 from locks import singleFlight
     18 from locks.singleFlight import single_flight
     19 from publicGateway.gateway import PublicGateway
     20 from signals import Signal
     21 logger = logging.getLogger(LOGGER_NAME)
     22 _OWNED_TITLES_CACHE_TTL = 600
     23 _EQUIP_STATE_CACHE_TTL = 30
     24 if False:
     25     from typing import Dict, List
     26     from publicGateway.grpc.test.mock_publicGatewaySvc import MockPublicGateway
     27     from carbon.common.script.sys.serviceManager import ServiceManager
     28     from cosmetics.client.character.title.repository.test.setup import MockServiceManager
     29 
     30 class CharacterTitlesRepository(object):
     31     __startupdependencies__ = ['publicGatewaySvc']
     32     __notifyevents__ = ['OnSessionChanged', 'OnLanguageChanged']
     33 
     34     def __init__(self, public_gateway, service_manager):
     35         logger.info('initializing repository...')
     36         self._service_manager = service_manager
     37         self._public_gateway = public_gateway
     38         self._request_messenger = TitleRequestMessenger(self._public_gateway)
     39         self._notice_messenger = TitleNoticeListener(self._public_gateway)
     40         self._definitions_repository = None
     41         self._owned_titles = None
     42         self._equipped_titles = {}
     43         notice_listener_signal.on_title_granted_notice.connect(self._on_title_granted_notice)
     44         notice_listener_signal.on_title_revoked_notice.connect(self._on_title_revoked_notice)
     45         notice_listener_signal.on_set_notice.connect(self._on_set_notice)
     46         notice_listener_signal.on_check_version_notice.connect(self._on_check_version)
     47         self._service_manager.RegisterNotify(self)
     48         self._startup_definitions_repository()
     49 
     50     def __del__(self):
     51         notice_listener_signal.on_title_granted_notice.disconnect(self._on_title_granted_notice)
     52         notice_listener_signal.on_title_revoked_notice.disconnect(self._on_title_revoked_notice)
     53         notice_listener_signal.on_set_notice.disconnect(self._on_set_notice)
     54         notice_listener_signal.on_check_version_notice.disconnect(self._on_check_version)
     55         self._service_manager.UnregisterNotify(self)
     56         if self._definitions_repository is not None:
     57             self._definitions_repository.on_content_updated.disconnect(self._on_definitions_updated)
     58             self._definitions_repository = None
     59 
     60     @property
     61     def definitions(self):
     62         return self._definitions_repository
     63 
     64     @single_flight
     65     def get_owned_titles(self):
     66         self._cache_owned_titles()
     67         if self._owned_titles:
     68             return self._owned_titles.cache
     69         return []
     70 
     71     @single_flight
     72     def get_equipped_title(self, character_identifier):
     73         self._cache_equipped_title(character_identifier)
     74         if character_identifier in self._equipped_titles:
     75             return self._equipped_titles[character_identifier].equipped_state
     76 
     77     @single_flight
     78     def equip_title(self, title_identifier):
     79         char_identifier = CharacterIdentifier(session.charid)
     80         try:
     81             if title_identifier is not None:
     82                 self._request_messenger.equip_title_request(title_identifier)
     83             else:
     84                 self._request_messenger.unequip_title_request()
     85             if char_identifier in self._equipped_titles:
     86                 self._equipped_titles.pop(char_identifier)
     87             equipped_state = EquippedTitleStateAttributes(equipped_title=title_identifier)
     88             self._add_equipped_title_to_cache(char_identifier, equipped_state)
     89             api_signal.on_title_equipped_changed(char_identifier, equipped_state)
     90         except Exception as e:
     91             logger.error('unable to equip title %s for character %s' % (title_identifier, char_identifier), exc_info=e)
     92 
     93     @single_flight
     94     def admin_grant_title(self, title_identifier):
     95         if not session.role & ROLE_QA:
     96             return
     97         try:
     98             self._request_messenger.admin_grant_request(title_identifier)
     99         except Exception as e:
    100             logger.error('unable to admin grant title %s' % title_identifier, exc_info=e)
    101 
    102     @single_flight
    103     def admin_revoke_title(self, title_identifier):
    104         if not session.role & ROLE_QA:
    105             return
    106         try:
    107             self._request_messenger.admin_revoke_request(title_identifier)
    108         except Exception as e:
    109             logger.error('unable to admin revoke title %s' % title_identifier, exc_info=e)
    110 
    111     def admin_clear_disk_cache(self):
    112         self.definitions.admin_clear_disk_cache()
    113 
    114     def _startup_definitions_repository(self, check_for_updates = False):
    115         if self._definitions_repository is not None:
    116             self._definitions_repository.on_content_updated.disconnect(self._on_definitions_updated)
    117             self._definitions_repository.on_no_content_updated.disconnect(self._on_definitions_updated_noop)
    118             self._definitions_repository = None
    119             api_signal.on_definitions_invalidated()
    120         language = GetLanguageID()
    121         logger.info('creating definitions repository for language {l}...'.format(l=language))
    122         self._definitions_repository = TitleLocalizedDefinitionsRepository(self._public_gateway, language)
    123         self._definitions_repository.on_content_updated.connect(self._on_definitions_updated)
    124         self._definitions_repository.on_no_content_updated.connect(self._on_definitions_updated_noop)
    125         if check_for_updates:
    126             self._definitions_repository.check_version_and_prime(None)
    127 
    128     def _cache_owned_titles(self):
    129         if self._owned_titles is None or self._owned_titles.is_expired:
    130             self._make_owned_titles_request()
    131 
    132     def _make_owned_titles_request(self):
    133         try:
    134             page = ''
    135             owned_titles = []
    136             while page is not None:
    137                 owned_titles_page, page = self._request_messenger.get_owned_titles_request(page)
    138                 owned_titles.extend(owned_titles_page)
    139 
    140             self._owned_titles = CachedOwnedTitles(owned_titles=owned_titles, expiration=datetime.now() + timedelta(seconds=_OWNED_TITLES_CACHE_TTL))
    141         except Exception as e:
    142             logger.error('unable to cache owned titles', exc_info=e)
    143 
    144     def _cache_equipped_title(self, character_identifier):
    145         if character_identifier not in self._equipped_titles or self._equipped_titles[character_identifier].is_expired:
    146             self._make_get_equipped_title_request(character_identifier)
    147 
    148     def _make_get_equipped_title_request(self, character_identifier):
    149         try:
    150             equipped_state = self._request_messenger.get_equipped_title_request(character_identifier)
    151             self._add_equipped_title_to_cache(character_identifier, equipped_state)
    152         except Exception as e:
    153             logger.error('unable to cache equipped title for character %s' % character_identifier, exc_info=e)
    154 
    155     def _add_equipped_title_to_cache(self, character_identifier, equipped_state):
    156         self._equipped_titles[character_identifier] = CachedEquippedTitleAttributes(equipped_state=equipped_state, expiration=datetime.now() + timedelta(seconds=_EQUIP_STATE_CACHE_TTL))
    157 
    158     def _clear_cache(self):
    159         self._equipped_titles = {}
    160         self._clear_character_session_cache()
    161 
    162     def _clear_character_session_cache(self):
    163         self._owned_titles = None
    164 
    165     def OnSessionChanged(self, _is_remote, _session, change):
    166         if 'charid' in change:
    167             self._clear_character_session_cache()
    168             if self._definitions_repository.get_current_version_in_memory() is None:
    169                 logger.info("definitions aren't loaded yet as character enters game, manually fetching")
    170                 self._definitions_repository.check_version_and_prime(None)
    171 
    172     def OnLanguageChanged(self, _language_id):
    173         logger.info('language changed, reloading definitions')
    174         self._startup_definitions_repository(True)
    175 
    176     def _on_definitions_updated(self, *args):
    177         logger.info('definitions loaded')
    178         api_signal.on_definitions_loaded()
    179 
    180     def _on_definitions_updated_noop(self, *args):
    181         logger.info('definitions loaded - everything was already up-to-date')
    182 
    183     def _on_check_version(self, version):
    184         logger.info('check version notice received with version %s', version)
    185         self.definitions.check_version_and_prime(version)
    186 
    187     def _on_title_granted_notice(self, title_identifier):
    188         if self._owned_titles is not None and not self._owned_titles.is_expired:
    189             self._owned_titles.cache.append(title_identifier)
    190         else:
    191             self._cache_owned_titles()
    192         api_signal.on_title_granted(title_identifier)
    193 
    194     def _on_title_revoked_notice(self, title_identifier):
    195         if self._owned_titles is not None and not self._owned_titles.is_expired:
    196             if title_identifier in self._owned_titles.cache:
    197                 self._owned_titles.cache.remove(title_identifier)
    198         else:
    199             self._cache_owned_titles()
    200         api_signal.on_title_revoked(title_identifier)
    201 
    202     def _on_set_notice(self, character_identifier, equipped_state):
    203         self._add_equipped_title_to_cache(character_identifier, equipped_state)
    204         api_signal.on_title_equipped_changed(character_identifier, equipped_state)