def _action_battle_report(cid, user, content, update, context): """ Update user info from battle report """ if settings.VERBOSE: print(" Battle report") try: user.cw_name = content.split(settings.GUILD_NAME)[1].split( b' \\u2694:')[0].decode("unicode_escape") user.cw_level = int( content.split(b' Lvl: ')[1].split(b'\\n')[0].decode( "unicode_escape")) if user.cw_name and user.cw_level: if model.user_by_id(update.effective_user.id): status = model.update_user(user) else: status = model.subscribe(user) if settings.VERBOSE: print(" {0} Lvl: {1} Status: {2}".format( user.cw_name, user.cw_level, status)) except Exception as e: utils._admin_error(context, "_action_battle_report: battle report", user=user, error=str(e))
def _action_roster(cid, user, content, update, context): """ Show sleepy members """ content = content.split(b'\\n')[1:] # check UTC battle utcnow = datetime.datetime.utcnow() time_list = [] for t in settings.BATTLES: time_list.append( (utcnow - datetime.datetime(year=utcnow.year, month=utcnow.month, day=utcnow.day, hour=int(t[0:2]), minute=int(t[3:5]))).total_seconds() / 60.0) delta = int(model.get_data("BATTLE_TIME_DELTA_MINUTES", 20)) time_list = [t > -delta and t < 0 for t in time_list] print(" Roster", time_list, delta) # call to the battle if True in time_list: i = 0 tmp = "" header = u'\U0001F4E2 The battle is coming\n' for player in content: if b' [\\u2694] ' not in player and b' [\\U0001f6e1] ' not in player and b' [\\U0001f4a4] ' not in player: cw_name = b' '.join(player.split(b' ')[3:]).decode() user = model.user_by_cw_name(cw_name) if user: tmp += "@{0} ".format(user.username) i += 1 if not i % 3: i = 0 try: if tmp: context.bot.send_message( chat_id=cid, text=header + tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "_action_roster: attention", user=user, error=str(e)) tmp = "" if tmp: try: context.bot.send_message(chat_id=cid, text=header + tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "_action_roster: attention", user=user, error=str(e))
def _error(update, context): logger.warning('Update "%s" caused error "%s"', update, context.error) # send the error message to the admin utils._admin_error(context, "INTERNAL ERROR", error=str(context.error)) return # send the error message to current user if is valid try: context.bot.send_message(chat_id=update.effective_user.id, text=settings.MESSAGES["application-error"].format(update._effective_message.text, context.error), parse_mode=telegram.ParseMode.HTML) except Exception as e: print("[EXCEPTION] user _error", e)
def message(update, context): """ Send a message to each user """ try: if str(update.effective_user.id) == settings.ADMIN_ID: # message hint if update.message.text == "/message": text = 'Use /message <i>text</i> for send the current text to each subscribed user\n\nThe text can be formatted:\n{0} user full name\n{1} admin link' context.bot.send_message(chat_id=settings.ADMIN_ID, text=text, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) # build and send message else: text = update.message.text[9:] text.format("", html.escape(settings.ADMIN_CONTACT)) counter_success = 0 counter_fail = 0 list_fail = [] users = model.users() for user in users: try: context.bot.send_message( chat_id=user.id, text=text.format( html.escape(user.full_name), html.escape(settings.ADMIN_CONTACT)), parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) counter_success += 1 except Exception as e: counter_fail += 1 list_fail.append(user.full_name) # send report to the admin report_text = '<b>Message:</b> {0}\n\n<b>Subscribed users:</b> {1}\n<b>Successful deliveries:</b> {2}\n<b>Unsuccessful deliveries:</b> {3}'.format( text.format("USER", html.escape(settings.ADMIN_CONTACT)), len(users), counter_success, counter_fail) if list_fail: report_text += "\n<b>Unsuccessful users:</b> {0}".format( ", ".join(list_fail)) context.bot.send_message(chat_id=settings.ADMIN_ID, text=report_text, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "/message", error=str(e), trace=False)
def elite(update, context): """ Mention the elite """ cid=update.message.chat.id # validate user if not utils._check_user(context, update.effective_user.id, cid): return # telegram user user=model.User(id=update.effective_user.id, username=update.effective_user.username, full_name=update.effective_user.full_name, link=update.effective_user.link, is_bot=update.effective_user.is_bot) # mention users users=model.users() i=0 tmp="" max_cw_level=0 for u in users: if u.cw_level>max_cw_level: max_cw_level=u.cw_level for u in users: if u.id==str(update.effective_user.id) or u.cw_level<max_cw_level-model.get_data("MENTION_ELITE_DELTA", 15): continue tmp+="@{0} ".format(u.username) i+=1 if not i%3: i=0 try: context.bot.send_message(chat_id=cid, text=u"\U0000270A Sir! Yes Sir!\n"+tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "/elite", user=user, error=str(e)) tmp="" if tmp: try: context.bot.send_message(chat_id=cid, text=u"\U0000270A Sir! Yes Sir!\n"+tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "/elite", user=user, error=str(e))
def _action_deposit(cid, user, content, update, context): """ Modify amount of items after deposit """ item = b' '.join(content.split(b' ')[2:-1]).decode()[10:] amount = int(content.split(b' ')[-1][1:-1]) print(" Deposit: {0} x ({1})".format(item, amount)) item = utils.item_by_name(item) if item: item_type = "" if item["code"].startswith('r'): item_type = "recipes" elif item["code"].startswith('k'): item_type = "parts" # modify the crafting data if item_type: # guild warehouse if item["name"].lower() in CACHE["guild"][item_type]: CACHE["guild"][item_type][item["name"].lower()] += amount else: CACHE["guild"][item_type][item["name"].lower()] = amount # user u = model.user_by_id(update.effective_user.id) if u: crafting = json.loads(u.crafting) if crafting and len(crafting.keys()): if item["name"].lower() in crafting[item_type]: crafting[item_type][item["name"].lower()] -= amount if crafting[item_type][item["name"].lower()] < 1: del crafting[item_type][item["name"].lower()] # store data user.crafting = json.dumps(crafting) if model.user_by_id(update.effective_user.id): status = model.update_user(user) if not status: utils._admin_error(context, "_action_deposit", user=user, error="update: False", trace=False) else: utils._admin_error(context, "_action_deposit", user=user, error="no registered user", trace=False)
def _action_crafting_list(cid, user, content, update, context): """ Update crafting list """ print(" Crafting tab") data = {"parts": {}, "recipes": {}, "datetime": None} today = datetime.datetime.today().isoformat() for c in content.split(b'\\n'): tmp = c # check false positive messages if b':' in tmp: continue # recipe if c.startswith(b'\\U0001f4c3'): # tmp=c.split(b'\\U0001f4c3')[1].split(b' /view_r')[0] tmp = c.split(b'\\U0001f4c3')[1].split(b' /i_r')[0] tmp = tmp.split(b' (') if len(tmp) == 2 and tmp[1].endswith(b')'): c_name = tmp[0].decode().lower() c_amount = int(tmp[1][:-1]) data["recipes"][c_name] = c_amount data["datetime"] = today # part elif c.startswith(b'\\U0001f9e9'): tmp = c.split(b'\\U0001f9e9')[1].split(b' (') if len(tmp) == 2 and tmp[1].endswith(b')'): c_name = tmp[0].decode().lower() c_amount = int(tmp[1][:-1]) data["parts"][c_name] = c_amount data["datetime"] = today if data["datetime"]: user.crafting = json.dumps(data) if model.user_by_id(update.effective_user.id): status = model.update_user(user) if not status: utils._admin_error(context, "_action_crafting_list", user=user, error="update: False", trace=False) else: utils._admin_error(context, "_action_crafting_list", user=user, error="no registered user", trace=False)
def everybody(update, context): """ Mention all subscribed users """ cid=update.message.chat.id # validate user if not utils._check_user(context, update.effective_user.id, cid): return # telegram user user=model.User(id=update.effective_user.id, username=update.effective_user.username, full_name=update.effective_user.full_name, link=update.effective_user.link, is_bot=update.effective_user.is_bot) # mention users users=model.users() i=0 tmp="" for u in users: if u.id==str(update.effective_user.id): continue tmp+="@{0} ".format(u.username) i+=1 if not i%3: i=0 try: context.bot.send_message(chat_id=cid, text=tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "/everybody", user=user, error=str(e)) tmp="" if tmp: try: context.bot.send_message(chat_id=cid, text=tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "/everybody", user=user, error=str(e))
def stomp(update, context): """ Mention stronger users for stomp the hostile creatures """ if settings.VERBOSE: print("[REGEX] help for stomp hostile creatures") cid=update.message.chat.id # validate user if not utils._check_user(context, update.effective_user.id, cid): return # telegram user user=model.User(id=update.effective_user.id, username=update.effective_user.username, full_name=update.effective_user.full_name, link=update.effective_user.link, is_bot=update.effective_user.is_bot) # parse message msg=update.message.text[7:].split("@")[0].split("_") if settings.VERBOSE: print(" ", msg) # validate the user if msg[1]==str(update.effective_user.id): # list users users=model.filtered_users(user, int(msg[0]), 20) i=0 tmp="" for u in users[1]: if u.id==str(update.effective_user.id): continue tmp+="@{0} ".format(u.username) i+=1 if not i%3: i=0 try: context.bot.send_message(chat_id=cid, text="Someone needs your help for stomp the hostile creatures\n"+tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "regex stomp: accepted", user=user, error=str(e)) tmp="" if tmp: try: context.bot.send_message(chat_id=cid, text="Someone needs your help for stomp the hostile creatures\n"+tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "regex stomp: accepted", user=user, error=str(e)) else: try: context.bot.send_message(chat_id=cid, text=u'\U0001F622 Only the owner of this encounter can request for help', parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "regex stomp: denied", user=user, error=str(e))
def check_outdata_crafting_list(): while True: time.sleep(int(model.get_data("CRAFT_OUTDATE_INTERVAL_HOURS", 8*3600))) cid=model.get_data("CRAFTING_ROOM_CHAT_ID", None) print("[TIMER] check_outdata_crafting_list:", cid) if cid: today=datetime.datetime.today() try: for u in model.users(): crafting=json.loads(u.crafting) if crafting and len(crafting.keys()): # validate the date t=datetime.datetime.fromisoformat(crafting["datetime"]) tmp=(datetime.datetime.today()-t).total_seconds()/(24.0*3600.0) if tmp>int(model.get_data("CRAFT_OUTDATE_INTERVAL_DAYS", 3)): BOT.send_message(chat_id=cid, text=u'@{0}, your crafting data is outdated. Please, forward it here...'.format(html.escape(u.username)), parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: class Context: bot=BOT context=Context() utils._admin_error(context, "timer.check_outdata_crafting_list", error=str(e))
def users(update, context): """ List the subscribed users """ try: if str(update.effective_user.id) == settings.ADMIN_ID: users = model.users() # summary if update.message.text == "/users": text = u'<b>Subscribed users:</b> {0}\n\nUse /users_list for display the full list\nUse /users_detail for display detailed info (a lot of messages)'.format( len(users)) context.bot.send_message(chat_id=settings.ADMIN_ID, text=text, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) # full list elif update.message.text == "/users_list": text = "" for user in users: tmp = u'\U0001F539 {0} {1}\n @{2}\n'.format( user.cw_level, html.escape(user.cw_name), html.escape(user.username)) if len(text) + len( tmp) < telegram.constants.MAX_MESSAGE_LENGTH - 5: text += tmp else: context.bot.send_message(chat_id=settings.ADMIN_ID, text=text, disable_web_page_preview=True) text = "" if text: context.bot.send_message(chat_id=settings.ADMIN_ID, text=text, disable_web_page_preview=True) # detailed list elif update.message.text == "/users_detail": for user in users: text = "<b>id:</b> {0}\n<b>username:</b> {1}\n<b>full_name:</b> {2}\n<b>link:</b> {3}\n<b>cw_name:</b> {4}\n<b>cw_level:</b> {5}\n<b>updated:</b> {6}\n<b>crafting:</b> {7}\n\n<code>/craft_reset {0}</code>\n<code>/users_delete {0}</code>".format( user.id, html.escape(user.username), html.escape(user.full_name), html.escape(user.link), html.escape(user.cw_name), user.cw_level, html.escape(user.updated), html.escape(user.crafting)) context.bot.send_message( chat_id=settings.ADMIN_ID, text=text, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) # delete user elif update.message.text.split(" ")[0] == "/users_delete" and len( update.message.text.split(" ")) == 2: user = model.user_by_id(update.message.text.split(" ")[1]) if user: status = model.unsubscribe(user) context.bot.send_message( chat_id=settings.ADMIN_ID, text="User unsubscription operation [{1}]... for @{0}". format(html.escape(user.username), status), parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "/users", error=str(e), trace=False)
def forwarded(update, context): """ Main handler function for forwarded messages """ global CACHE cid = update.message.chat.id # validate user if not utils._check_user(context, update.effective_user.id, cid): return # process forward message from Chat Wars if update.message.forward_from and update.message.forward_from.id == settings.CW_BOT_ID: if settings.VERBOSE: print("[Forwarded] from Chat Wars") # telegram user user = model.User(id=update.effective_user.id, username=update.effective_user.username, full_name=update.effective_user.full_name, link=update.effective_user.link, is_bot=update.effective_user.is_bot) # create cache CACHE.setdefault( user.id, { "resources": { "guild": {}, "reinforcement": {}, "datetime": datetime.datetime.today() } }) CACHE.setdefault("guild", { "resources": {}, "parts": {}, "recipes": {} }) # escape content try: content = update.message.text.encode(encoding="unicode_escape") # print(content) except Exception as e: utils._admin_error(context, "encode message", user=user, error=str(e), trace=False) return # hostile creatures if b'You met some hostile creatures. Be careful:' in content and b'/fight_' in content: _action_fight(cid, user, content, update, context) return # battle report if settings.GUILD_NAME in content and b' Lvl: ' in content and b'Your result on the battlefield' in content: _action_battle_report(cid, user, content, update, context) return # materials needed for reinforcement (blacksmith's store message) if content.split(b'\\n')[0].startswith(b'Materials needed for '): _action_reinforcement(cid, user, content, update, context) return # guild warehouse if content.split(b'\\n')[0].startswith(b'Guild Warehouse:'): _action_reinforcement(cid, user, content, update, context) return # guild roster if content.split(b'\\n')[0].startswith( settings.GUILD_NAME[:10]) and content.split( b'\\n')[-1].startswith(b'#'): _action_roster(cid, user, content, update, context) return # guild deposit if content.startswith(b'Deposited successfully: '): _action_deposit(cid, user, content, update, context) return # parts and recipes if (content.startswith(b'\\U0001f4c3') or content.startswith(b'\\U0001f9e9') ) and not (b'Equipment' in content or b'Storage' in content or b'/use_' in content or b'U0001f3f7' in content): _action_crafting_list(cid, user, content, update, context) return # alliances top if content.split(b'\\n')[0] == b'\\U0001f91dAlliances top:': _alliances_top(cid, user, content, update, context) return
def _action_fight(cid, user, content, update, context): """ Mention users for a fight """ header = "Just another fight!\n" delta_upper = 10 delta_lower = 20 # forbidden champion if b"Forbidden Champion lvl." in content: header = u"\U000026A0 Defeat the \U0000269C CHAMPION!\n\U0001F534 Don't join if you can stomp\n" # delta_upper=1000 delta_upper = 15 delta_lower = 1000 # ambush with loot locked elif b"It's an ambush! Loot is locked till the end of the fight" in content: header = u"\U0001F4E6 Ambush with loot locked!\n" delta_upper = 15 # ambush without loot elif b"It's an ambush!" in content: header = "Ambush without loot!\n" delta_upper = 15 # animals hunt elif b"Bear" in content or b"Boar" in content or b"Wolf" in content: header = u"\U0001F417 Wild animals hunt!\n" if settings.VERBOSE: print(" Hostile creatures:", delta_lower, delta_upper, header) # mention users users = model.filtered_users(user, delta_upper, delta_lower) i = 0 tmp = "" for u in users[0]: if u.id == str(update.effective_user.id): continue tmp += "@{0} ".format(u.username) i += 1 if not i % 3: i = 0 try: context.bot.send_message(chat_id=cid, text=header + tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "_action_fight: hostile creatures", user=user, error=str(e)) tmp = "" if tmp: try: context.bot.send_message(chat_id=cid, text=header + tmp, parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "_action_fight: hostile creatures", user=user, error=str(e)) # stomp message if len(users[1]): try: context.bot.send_message( chat_id=cid, text= "You can call for help from stronger players to stomp the hostile creatures\n/stomp_{0}_{1}" .format(delta_upper, user.id), parse_mode=telegram.ParseMode.HTML, disable_web_page_preview=True) except Exception as e: utils._admin_error(context, "_action_fight: hostile creatures", user=user, error=str(e))