chat_service.py (9567B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\chat\client\chat_service.py 2 from __future__ import print_function 3 from featuremanagement.client.flag import flag_bool 4 from carbon.common.script.sys.service import Service 5 import carbonui.const as uiconst 6 import uthread2 7 from carbon.common.script.util.format import FmtDate 8 from eveexceptions import UserError 9 import signals 10 from chat.common.const import ChatCategory, LOCAL_CHAT_FEATURE_FLAG_KEY, LOCAL_CHAT_FEATURE_FLAG_FALLBACK 11 from chat.common.util import get_classification_from_role 12 from chat.client.window import ChatWindow 13 from chat.client.local_chat.channel_controller import LocalChatChannelController 14 from chat.client.local_chat.validators.paste import DefaultValidator 15 from player_messaging.client.ui_message import prompt_player_fsd_dialog 16 _category_channel_class = {ChatCategory.LOCAL: LocalChatChannelController} 17 18 class ChatSvc(Service): 19 __guid__ = 'svc.chat' 20 __displayname__ = 'Chat Service' 21 __notifyevents__ = ['OnSessionChanged', 'ProcessSessionReset'] 22 __dependencies__ = [] 23 __startupdependencies__ = ['publicGatewaySvc'] 24 25 def __init__(self): 26 super(ChatSvc, self).__init__() 27 self._members_info = {} 28 self.on_member_data_changed = signals.Signal('on_member_info_changed') 29 self.on_member_data_changed_live_update = signals.Signal('on_member_info_changed_live_update') 30 self._reported_spammer_ids = set() 31 self._chat_channels = {} 32 self._is_local_chat_service_enabled = None 33 self._load_local_tasklet = None 34 self._paste_validators = {} 35 self._default_paste_validator = DefaultValidator() 36 37 def Run(self, memStream = None): 38 Service.Run(self, memStream) 39 flag_bool(key=LOCAL_CHAT_FEATURE_FLAG_KEY, default_value=LOCAL_CHAT_FEATURE_FLAG_FALLBACK, callback=self._on_local_chat_service_flag_changed) 40 41 def OnSessionChanged(self, is_remote, session, change): 42 if 'charid' in change or 'corpid' in change or 'allianceid' in change or 'warfactionid' in change: 43 if 'charid' in change: 44 if self._is_local_chat_service_enabled and not self._load_local_tasklet: 45 self._load_local_tasklet = uthread2.start_tasklet(self._load_local_channel) 46 self._update_self_from_session() 47 48 def ProcessSessionReset(self): 49 self.flush() 50 51 def flush(self): 52 self._members_info.clear() 53 if self._load_local_tasklet: 54 self._load_local_tasklet.kill() 55 self._load_local_tasklet = None 56 for channel_id in self._chat_channels.keys(): 57 self.close_channel(channel_id) 58 59 def add_paste_validator(self, validator): 60 if validator.identifier not in self._paste_validators: 61 self._paste_validators[validator.identifier] = validator 62 63 def remove_paste_validator(self, validator): 64 if validator.identifier in self._paste_validators: 65 self._paste_validators.pop(validator.identifier) 66 67 def validate_paste(self, text): 68 for validator in self._paste_validators.values(): 69 result = validator.validate(text) 70 if result: 71 return result 72 73 return self._default_paste_validator.validate(text) 74 75 @property 76 def is_local_chat_service_enabled(self): 77 return self._is_local_chat_service_enabled 78 79 def _on_local_chat_service_flag_changed(self, evaluate_flag): 80 is_enabled = evaluate_flag() 81 if self._is_local_chat_service_enabled == is_enabled: 82 return 83 self._is_local_chat_service_enabled = is_enabled 84 if not self._load_local_tasklet: 85 self._load_local_tasklet = uthread2.start_tasklet(self._load_local_channel) 86 87 def get_member_info(self, member_id): 88 return self._members_info.get(member_id, {}) 89 90 def has_member_info(self, member_id): 91 return member_id in self._members_info 92 93 def update_members_info(self, members, signal = False): 94 for member_id, member_info in members.iteritems(): 95 self._members_info[member_id] = member_info 96 if signal: 97 self.on_member_data_changed(member_id, member_info) 98 99 def add_game_message(self, text, sender_id = None): 100 if self.is_local_chat_service_enabled: 101 channel = self.get_channel(ChatCategory.LOCAL) 102 if channel: 103 channel.add_game_message(text, sender_id) 104 else: 105 sm.GetService('XmppChat').LocalEchoAll(text, sender_id) 106 107 def get_channel(self, channel_id): 108 return self._chat_channels.get(channel_id, None) 109 110 def join_channel(self, channel_id, category_id, open = True): 111 if channel_id not in self._chat_channels: 112 channel_class = _category_channel_class.get(category_id, None) 113 if channel_class: 114 self._chat_channels[channel_id] = channel_class(channel_id=channel_id, category_id=category_id) 115 if open: 116 self.open_channel_window(channel_id) 117 118 def close_channel(self, channel_id): 119 channel = self._chat_channels.pop(channel_id, None) 120 if channel: 121 channel.close() 122 try: 123 window = ChatWindow.GetIfOpen(windowID=channel.window_id) 124 if window: 125 window.Close() 126 except: 127 pass 128 129 def open_channel_window(self, channel_id): 130 channel = self.get_channel(channel_id) 131 if not channel: 132 return 133 ChatWindow(windowID=channel.window_id, caption=channel.window_display_name, controller=channel, check_open_minimized=True) 134 135 def invite_to_private_chat(self, character_id): 136 sm.GetService('XmppChat').Invite(character_id) 137 138 def is_blocked_character(self, character_id, character_info): 139 address_book = sm.GetService('addressbook') 140 try: 141 return address_book.IsBlocked(character_id) or address_book.IsBlocked(character_info.get('corporation_id')) or address_book.IsBlocked(character_info.get('alliance_id')) 142 except: 143 return False 144 145 def has_reported_spammers(self): 146 return bool(self._reported_spammer_ids) 147 148 def clear_reported_spammers(self): 149 self._reported_spammer_ids.clear() 150 151 def is_reported_spammer(self, character_id): 152 return character_id in self._reported_spammer_ids 153 154 def report_isk_spammer(self, character_id, channel_id): 155 if prompt_player_fsd_dialog('ConfirmReportISKSpammer', {'name': cfg.eveowners.Get(character_id).name}, uiconst.YESNO) != uiconst.ID_YES: 156 return 157 if character_id == session.charid: 158 raise UserError('ReportISKSpammerCannotReportYourself') 159 if self.is_reported_spammer(character_id): 160 return 161 self._reported_spammer_ids.add(character_id) 162 all_messages = [] 163 channel = self.get_channel(channel_id) 164 if channel: 165 all_messages = list(channel.messages) 166 else: 167 xmpp_window = sm.GetService('XmppChat').GetGroupChatWindow(channel_id) 168 if xmpp_window: 169 all_messages = list(xmpp_window.messages) 170 spam_entries = [] 171 character_info = cfg.eveowners.GetIfExists(character_id) 172 character_name = character_info.name if character_info else character_id 173 for sender_id, text, timestamp, color in reversed(all_messages): 174 if sender_id != character_id: 175 continue 176 spam_entries.append('[%s] %s > %s' % (FmtDate(timestamp, 'nl'), character_name, text)) 177 if len(spam_entries) >= 10: 178 break 179 180 sm.RemoteSvc('userSvc').ReportISKSpammer(character_id, channel_id, spam_entries) 181 182 def get_player_count_in_local(self): 183 result = 0 184 if self.is_local_chat_service_enabled: 185 channel = self.get_channel(ChatCategory.LOCAL) 186 if channel: 187 result = channel.member_count 188 else: 189 result = sm.GetService('XmppChat').GetNumPilotsInSystem() 190 return result or 0 191 192 def _load_local_channel(self): 193 uthread2.sleep(0.5) 194 self._load_local_tasklet = None 195 channel_id = ChatCategory.LOCAL 196 if self.is_local_chat_service_enabled: 197 sm.GetService('XmppChat').UpdateLocalChatMigrated(self.is_local_chat_service_enabled) 198 self.join_channel(category_id=channel_id, channel_id=channel_id, open=False) 199 else: 200 self.close_channel(channel_id) 201 sm.GetService('XmppChat').UpdateLocalChatMigrated(self.is_local_chat_service_enabled) 202 203 def _update_self_from_session(self): 204 if session.charid: 205 self._members_info[session.charid] = {'corporation_id': session.corpid, 206 'alliance_id': session.allianceid, 207 'war_faction_id': session.warfactionid, 208 'classification': get_classification_from_role(session.role)} 209 210 def mute_player(self, character_id, channel_id, duration_seconds, reason): 211 if channel_id == 'local': 212 print('GAGGING FOR LOCAL') 213 self.get_channel(channel_id).mute_player(character_id, duration_seconds, reason) 214 else: 215 sm.ProxySvc('XmppChatMgr').GMMute(channel_id, character_id, reason, duration_seconds) 216 217 def unmute_player(self, character_id, channel_id): 218 if channel_id == 'local': 219 raise NotImplementedError('Unmute not implemented for local chat') 220 else: 221 sm.ProxySvc('XmppChatMgr').GMUnmute(channel_id, character_id)