def just_embrace_say(user, clan_name, get_text=False): if not (user or clan_name): return False pander = (clan_name == 'Pander') sir = None if not pander: clan_users = set() not_sire_ids = {user.id}.union(C.not_sir).union(ram.embrace_not) for mem in C.client.get_all_members(): if other.find(mem.roles, id=C.roles[clan_name]) and mem.id not in not_sire_ids: clan_users.add(mem.id) if clan_users: embr_first = [userid for userid in ram.embrace_first if userid in clan_users] if embr_first: sir = embr_first[0] ram.embrace_first.remove(sir) else: sir = other.choice(list(clan_users)) text = com.get_t('embrace_msg', sir=f'<@{sir}>', child=f'<@{user.id}>') else: text = com.get_t('embrace_unic', clan=f'<@&{C.roles[clan_name]}>', child=f'<@{user.id}>') else: text = com.get_t('embrace_pander', child=f'<@{user.id}>') if clan_name in C.sabbat_clans and not pander: text += "\n" + com.get_t('embrace_sabbat') if get_text: return text else: com.write_msg(C.main_ch, text) return sir
def _beckett_ans(m_type, author_id): prob = other.rand() ans = None keys = {'sm_resp'} punct = True name_phr = False if not m_type: ans = '' elif 'no-response' in m_type: ans = 'no-response' elif m_type in {'wlc', 'bye', 'yes', 'no', 'hi_plus', 'not_funny', 'fun_smiles'}: keys.add(m_type) name_phr = True elif m_type == 'love': if author_id == C.users['Natali']: ans = (emj.e_str('a_Toreador_light'), emj.e_str('a_Toreador_wave')) if prob < 0.1 else ':purple_heart:' elif author_id == C.users['aleth_lavellan']: ans = ('💜', '❤', '💗', '😘', '💙', '♥', '💓', '💚', '💞', '💕', '💛', '💖', '🤗') elif author_id == C.users['AyrinSiverna']: ans = ('🌹', '🌷', '❤', '♥', '😘', '☺',) else: ans = (':heart:', ':hearts:', ':kissing_heart:', ':relaxed:') ans = other.name_phr(author_id, ans, punct=False) elif m_type == 'like': ans = 'no-response' elif m_type == 'apoliticality': keys.add(m_type) elif m_type == 'tremer_joke': ans = data.tremer_joke elif m_type == 'bot_dog': ans = com.get_t('threats', name=author_id) elif m_type == 'shchupalko': ans = f"<@{author_id}> {emj.e(other.choice('s_shchupalko0', 's_shchupalko1', 's_shchupalko3'))}" elif m_type in {'whatsup', 'question'}: keys = {m_type} elif m_type == 'boring': ans = other.name_phr(author_id, 'я тоже') else: ans = '' if ans is None: text = com.get_t(all_keys=keys) punct = punct and text not in data.sm_resp['ans_smiles'] ans = other.name_phr(author_id, text, punct=punct) if name_phr else text return ans
def _timer_check_games(): for usr in user_games: user_games[usr]['h'] += 1 g_name = user_games[usr]['name'].lower() if (usr not in ram.ignore_users and user_games[usr]['h'] % (2 * TMR_IN_H) == 0 and all(word in g_name for word in VTMB)): phr = com.get_t('vtmb', user=f'<@{usr}>') com.write_msg(C.main_ch, phr)
def _timer_check_silence_in_chat(): if ram.last_vtm_msg and ( (other.get_sec_total() - ram.last_vtm_msg) > 25200): # 7 hours log.I('<timer_quarter_h> silence event!') phr = com.get_t('silence', ) com.write_msg(C.main_ch, phr)
async def on_member_update_u(before: C.Types.Member, after: C.Types.Member): # it's triggers on changing status, game playing, avatar, nickname or roles # if after.id == C.users['bot']: return smth_happend = False a_n = other.uname(after) + f' [{after.id}]' if before.display_name != after.display_name or before.name != after.name: smth_happend = True b_n = other.uname(before) log.pr_news(f'<on_member_update> {b_n} change nickname to {a_n}.') if before.game != after.game: smth_happend = True if before.game and after.game: log.D( f'<on_member_update> {a_n} go play from {before.game.name} to {after.game.name}.' ) elif before.game: log.D(f'<on_member_update> {a_n} stop play {before.game.name}.') elif after.game: log.D(f'<on_member_update> {a_n} start play {after.game.name}.') else: log.D( f'<on_member_update> {{???}} {a_n} - game change, but there are no games...' ) if after.id == C.users['Natali']: if before.game and C.prm_server.me.game.name == before.game.name: await other.set_game('') if after.game and not C.prm_server.me.game: await other.set_game(after.game.name) user_g = user_games.pop(after.id, {'name': '', 'h': 0}) # degradation if False and other.rand() < 0.5 and ( before.game and before.game.name and after.id not in ram.ignore_users and people.was_writing( after.id, 48) and user_g['h'] >= TMR_IN_H): phr = com.get_t('game', user=f'<@{after.id}>', game=f"«{user_g['name']}»") com.write_msg(C.main_ch, phr) if after.game and after.game.name: user_games[after.id] = {'name': after.game.name, 'h': 0} if before.avatar_url != after.avatar_url: smth_happend = True urls = [] for url in (before.avatar_url, after.avatar_url): urls.append(' ?'.join(url.split('?', maxsplit=1))) b_url, a_url = urls if before.avatar_url and after.avatar_url: await log.pr_avs( f'<on_member_update> {a_n} change avatar from \n{a_url} \nto\n{b_url}' ) elif before.avatar_url: await log.pr_avs( f'<on_member_update> {a_n} delete avatar: \n{b_url}') elif after.avatar_url: await log.pr_avs(f'<on_member_update> {a_n} set avatar: \n{a_url}') else: log.I( f'<on_member_update> {{???}} {a_n} - avatar change, but there are no avatar_urls...' ) # small degradation if (other.rand() < 0.01 and after.avatar_url and after.id not in ram.ignore_users and people.was_writing(after.id, 48)): phr = com.get_t('new_avatar', user=f'<@{after.id}>') com.write_msg(C.main_ch, phr) if before.roles != after.roles: smth_happend = True old_roles = [('@&' + r.name) for r in before.roles if r not in after.roles] new_roles = [('@&' + r.name) for r in after.roles if r not in before.roles] if old_roles: log.pr_news( f'<on_member_update> {a_n} lost role(s): {", ".join(old_roles)}.' ) if new_roles: log.pr_news( f'<on_member_update> {a_n} get role(s): {", ".join(new_roles)}.' ) new_role_ids = {r.id for r in after.roles if r not in before.roles} new_clan_roles = C.clan_ids.intersection(new_role_ids) has_clan_before = other.has_roles(before, C.clan_ids) if after.id not in not_embrace and new_clan_roles and not has_clan_before: clan_id = other.choice(new_clan_roles) clan_name = C.role_by_id[clan_id] log.pr_news( f'<on_member_update> {a_n} get new clan role "{clan_name}" => call do_embrace.' ) manager.just_embrace_say(after, clan_name=clan_name) # if sir_id: # if clan_id in C.clan_channels: # clan_ch = C.clan_channels[clan_id] # phr = com.get_t(all_keys=('clan_welcome', clan_ch), user=f'<@{after.id}>', sir=f'<@{sir_id}>') # com.write_msg(clan_ch, phr) elif has_clan_before and C.roles['Pander'] in new_clan_roles: log.jI( f'<on_member_update> {a_n} go to Pander => delete other clan roles if it\'s exist.' ) del_clans_id = C.clan_ids.difference({C.roles['Pander']}) rem_roles = {r for r in after.roles if r.id in del_clans_id} if rem_roles: other.rem_roles(after, rem_roles, 'on_member_update_u[1]') str_rem_r = f"<@&{'>, <@&'.join(r.id for r in rem_roles)}>" phr = com.get_t('to_Pander', user=f'<@{after.id}>', old_clans=str_rem_r, pander=f"<@&{C.roles['Pander']}>") com.write_msg(C.main_ch, phr) elif C.roles['Mortal'] in new_role_ids: if has_clan_before: # go to food rem_roles = { r for r in after.roles if r.id not in C.mortal_can_have_roles } other.rem_roles(after, rem_roles, 'go to Mortal(food)') log.pr_news(f'<on_member_update> {a_n} go to food') else: # new user await C.client.send_message(C.main_ch, com.welcome_msg(before.id)) log.pr_news(f'<on_member_update> {a_n} welcome') if C.roles['Sabbat'] in new_role_ids: clan_ch = C.clan_channels[C.roles['Sabbat']] phr = com.get_t(all_keys=('clan_welcome', clan_ch), user=f'<@{after.id}>') com.write_msg(clan_ch, phr) if before.status != after.status or not smth_happend: people.online_change(after.id, after.status, force=before.status == after.status) # small degradation _check_status_change(after) if (smth_happend or people.is_online(after.id)) and before.roles == after.roles: on_user_life_signs(after.id)
async def reaction(message, edit=False): msg = Msg(message) # in vtm open channels, save date of last message if msg.is_vtm: save = msg.chid == C.channels['flood'] if not save: every_prm = msg.channel.overwrites_for(C.vtm_server.default_role) save = every_prm.read_messages is not False if save: ram.last_vtm_msg = other.get_sec_total() if msg.auid == C.users['bot']: if msg.original == data.tremer_joke: other.later_coro(20, msg.delete('tremer_joke')) if msg.auid in data.day_events: _emj_on_message(msg, False, edit) return if msg.torpor: await msg.delete('torpor') return if C.roles['Silence'] in msg.roles: await msg.delete('Silence') ram.silence_ans[msg.auid] = ram.silence_ans.setdefault(msg.auid, 0) + 1 if ram.silence_ans[msg.auid] < 4: msg.answer(f'Неугодный <@{msg.auid}> пытается нам нечто сказать, но заноза в сердце мешает...') return # delete messages containing forbidden links if not msg.admin: if any(link in msg.text for link in data.forbiddenLinks): log.I(f'<reaction> forbidden links') await msg.delete('forbidden links') msg.answer(com.get_t('threats', name=msg.auid)) return # delete double messages for last 60 sec if ( not msg.super and not msg.personal and not (msg.text.startswith('!r') or msg.text.startswith('!shuffle')) and not edit and not (msg.message.attachments or msg.message.embeds) ): txt_now = (msg.original + ''.join([str(att.get('url', other.rand())) for att in msg.message.attachments]) + ''.join([str(emb.get('url', other.rand())) for emb in msg.message.embeds])) get_sec_now = other.get_sec_total() new_last_msgs = [] user_last_msgs = last_msgs.get(msg.auid, []) for txt, date in user_last_msgs: if (get_sec_now - date) < 60: new_last_msgs.append((txt, date)) if txt == txt_now: await msg.delete('double messages') return new_last_msgs.append((txt_now, get_sec_now)) last_msgs[msg.auid] = new_last_msgs # log.D(f'last_msgs["{msg.author.name}"]: {len(last_msgs[msg.auid])}.') # log.D(f'txt_now: {txt_now}.') if not msg.is_bot: # if edit msg with "good_time" or command - do nothing resp = _data_msgs_check(msg) if edit and resp and (resp['type'].startswith('cmd_') or resp['type'] == 'gt'): return # if we have !cmd -> doing something if msg.text.startswith('!'): fun = re.match(r'!\w*', msg.text).group(0)[1:] if fun in msg.get_commands(): msg.prepare(fun) log.I(f'<reaction> [cmd] {fun}') _data_msgs_add(msg, 'cmd_' + fun) await getattr(cmd, fun)(msg) return m_type, text = _do_reaction(msg, edit) if edit: old_type = resp['type'] if resp else '' if old_type == m_type: return if old_type and not m_type: return if m_type and old_type and text: log.I(f'<reaction> edit [{old_type}] to [{m_type}]') typing = _data_tp_check(msg) if typing in com.msg_queue.get(msg.channel.id, ()) or old_type == 'no-response': com.rem_from_queue(msg.channel.id, typing) # and type new mess else: for mess in resp['ans']: await C.client.edit_message(mess, new_content=text) # if mess>1, all will be with the same text resp['type'] = m_type return # elif m_type and not old_type: else: m_type, text = _do_reaction(msg, edit) _send_reaction(msg, m_type, text, edit)
def _do_reaction(msg:Msg, edit=False) -> (str, str): m_type = None # embrace_or_return = False msg.prepare2() beckett_reference = bool(C.beckett_refs.intersection(msg.words)) beckett_mention = bool(C.beckett_names.intersection(msg.words)) beckett = beckett_reference or beckett_mention or msg.personal _emj_on_message(msg, beckett, edit) if (ram.mute_channels.intersection({msg.channel.id, 'all'}) or msg.auid in ram.ignore_users or msg.channel.id in C.ignore_channels or (msg.channel.id in ram.test_channels and not C.is_test)): # # turn off embrace by message # if msg.channel.id == C.channels['ask']: # embrace_or_return = True # else: # return '', '' return '', '' if msg.is_bot: m_type = 'bot' if (beckett_reference or beckett_mention) and other.rand() < 0.05: ans_phr = com.get_t(m_type) return m_type, ans_phr log.jD('Ignore bot') return 'no-response', '' found_keys = com.check_phrase(msg.text, msg.words) prob = other.rand() # # embrace # turn off embrace by message # if msg.channel.id == C.channels['ask'] and not msg.roles.intersection(C.clan_ids) and not msg.author.bot: # clan_keys = list(C.clan_names.intersection(found_keys)) # if clan_keys: # clan = other.choice(clan_keys) # other.later_coro(other.rand(20, 50), manager.do_check_and_embrace(msg.auid, clan_name=clan)) # # get 100% to comment of chosen clan # beckett = True # found_keys = clan # elif embrace_or_return: # return '', '' # if (msg.channel.id == C.channels['gallery'] and msg.auid in (C.users['Hadley'], C.users['Natali']) and # (msg.message.attachments or msg.message.embeds) and prob < 0.2): # log.jI('gallery event') # phr = com.get_t('gallery_picture', user=f'<@{msg.auid}>') # com.write_msg(C.main_ch, phr) gt = msg.check_good_time(beckett) if gt: return 'gt', gt elif gt == '': m_type = 'was-good-time no-response' if found_keys: if not beckett and ram.mute_light_channels.intersection({msg.channel.id, 'all'}): return '', '' response = False if msg.channel.id == C.channels['sabbat']: if 'Sabbat' in found_keys: found_keys.remove('Sabbat') found_keys.add('Sabbat2') if prob < 0.02 or beckett: response = True else: if prob < 0.2 or beckett: #beckett_reference or (beckett_mention and (prob < 0.9 or msg.admin)): response = True if response: ans_phr = com.get_text_obj(found_keys) if ans_phr['text']: t = ans_phr['text'] if ans_phr['last_key'] == 'Nosferatu' and other.rand() < 0.4: t = com.text2leet(ans_phr['text'], 0.25) elif ans_phr['last_key'] == 'Malkavian' and other.rand() < 0.4: t = com.text2malk(ans_phr['text'], 1) if ans_phr['last_key'] == 'Tarkin' and prob > 0.05 and not beckett: return '', '' return ans_phr['last_key'], t else: if other.check_fliproll(msg.original): if '┻' in msg.original: len_table = msg.original.count('━') len_wave = msg.original.count('︵') if msg.admin: return 'rand_tableflip', other.rand_tableflip(len_wave, len_table) elif msg.channel.id == C.channels['bar']: if C.roles['Primogens'] in msg.roles or prob < 0.2: if other.rand() < 0.05: return 'tableflip_phrase', com.get_t('tableflip_phrase') else: return 'rand_tableflip', other.rand_tableflip(len_wave, len_table) else: return 'unflip', '┬─┬ ノ( ゜-゜ノ)' else: dice_count = msg.original.count('dice') + msg.original.count('🎲') if dice_count > 0: return 'diceflip', other.rand_diceflip(dice_count) elif msg.original[1:].startswith('tableflip') and (msg.admin or msg.channel.id == C.channels['bar']): if not C.roles['Primogens'] in msg.roles and not msg.admin and prob < 0.2: return 'tableflip_phrase', com.get_t('tableflip_cmd_phrase', user=f'<@{msg.auid}>') else: return '/tableflip', '* *бросаю за <@{id}>* *\n{table}'.format(id=msg.auid, table=other.rand_tableflip()) elif msg.original[1:].startswith('shrug'): return '/shrug', r'¯\_(ツ)_/¯' m_type = m_type or (_beckett_m_type(msg) if beckett else _not_beckett_m_type(msg)) _emj_by_mtype(msg, m_type) ans = _beckett_ans(m_type, msg.auid) if ans: return m_type, ans if beckett: # beckett_reference or (beckett and other.rand() < 0.25): if prob < 0.1: ans_phr = com.get_t(all_keys=('author_phrases', msg.auid)) if ans_phr: return msg.auid, ans_phr m_type = 'For_Prince' if msg.auid == C.users['Natali'] and prob < 0.4 else 'beckett' ans_phr = com.get_t(m_type) return m_type, ans_phr return '', ''