def receive_watch_user(data: dict) -> bool: # Receive watch users that other bots shared try: # Basic data the_type = data["type"] uid = data["id"] until = data["until"] # Decrypt the data until = crypt_str("decrypt", until, glovar.key) until = get_int(until) # Add to list if the_type == "ban": glovar.watch_ids["ban"][uid] = until elif the_type == "delete": glovar.watch_ids["delete"][uid] = until else: return False save("watch_ids") return True except Exception as e: logger.warning(f"Receive watch user error: {e}", exc_info=True) return False
def resolve_username(client: Client, username: str, cache: bool = True) -> (str, int): # Resolve peer by username peer_type = "" peer_id = 0 try: username = username.strip("@") if not username: return "", 0 result = glovar.usernames.get(username) if result and cache: return result["peer_type"], result["peer_id"] result = resolve_peer(client, username) if result: if isinstance(result, InputPeerChannel): peer_type = "channel" peer_id = result.channel_id peer_id = get_int(f"-100{peer_id}") elif isinstance(result, InputPeerUser): peer_type = "user" peer_id = result.user_id glovar.usernames[username] = { "peer_type": peer_type, "peer_id": peer_id } except Exception as e: logger.warning(f"Resolve username {username} error: {e}", exc_info=True) return peer_type, peer_id
def unban(client: Client, message: Message) -> bool: # Unban a user if not message or not message.chat: return True # Basic data gid = message.chat.id mid = message.message_id try: # Check permission if not is_class_c(None, None, message): return True aid = message.from_user.id command_type, command_context = get_command_context(message) # Text prefix text = ( f"{lang('admin')}{lang('colon')}{code(aid)}\n" f"{lang('action')}{lang('colon')}{code(lang('action_unban'))}\n") # Check command format if not command_type: text += ( f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('command_usage'))}\n" ) thread(send_report_message, (15, client, gid, text)) return True # Get user id uid = get_int(command_context) if not uid: peer_type, peer_id = resolve_username(client, command_type) if peer_type == "user" and peer_id: uid = peer_id # Proceed if not uid: text += ( f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('command_para'))}\n" ) thread(send_report_message, (15, client, gid, text)) return True # Proceed text = unban_user(client, message, uid, aid) thread(send_report_message, (30, client, gid, text)) return True except Exception as e: logger.warning(f"Unban error: {e}", exc_info=True) finally: delete_message(client, gid, mid) return False
def version(client: Client, message: Message) -> bool: # Check the program's version result = False try: # Basic data cid = message.chat.id aid = message.from_user.id mid = message.message_id # Get command type command_type = get_command_type(message) # Check the command type if command_type and command_type.upper() != glovar.sender: return False # Version info git_change = bool( run("git diff-index HEAD --", stdout=PIPE, shell=True).stdout.decode().strip()) git_date = run("git log -1 --format='%at'", stdout=PIPE, shell=True).stdout.decode() git_date = get_readable_time(get_int(git_date), "%Y/%m/%d %H:%M:%S") git_hash = run("git rev-parse --short HEAD", stdout=PIPE, shell=True).stdout.decode() get_hash_link = f"https://github.com/scp-079/scp-079-{glovar.sender.lower()}/commit/{git_hash}" command_date = get_readable_time(message.date, "%Y/%m/%d %H:%M:%S") # Generate the text text = ( f"{lang('admin')}{lang('colon')}{mention_id(aid)}\n\n" f"{lang('project')}{lang('colon')}{code(glovar.sender)}\n" f"{lang('version')}{lang('colon')}{code(glovar.version)}\n" f"{lang('本地修改')}{lang('colon')}{code(git_change)}\n" f"{lang('哈希值')}{lang('colon')}{general_link(git_hash, get_hash_link)}\n" f"{lang('提交时间')}{lang('colon')}{code(git_date)}\n" f"{lang('命令发送时间')}{lang('colon')}{code(command_date)}\n") # Send the report message result = send_message(client, cid, text, mid) except Exception as e: logger.warning(f"Version error: {e}", exc_info=True) return result
def get_class_d_id(message: Message) -> (int, int): # Get Class D personnel's id uid = 0 mid = 0 try: r_message = message.reply_to_message if not r_message or not is_from_user(None, None, r_message): return 0, 0 if not is_class_c(None, None, r_message): uid = r_message.from_user.id mid = r_message.message_id elif r_message.from_user.is_self: uid = get_int( r_message.text.split("\n")[0].split(lang("colon"))[1]) if uid in glovar.admin_ids[message.chat.id]: uid = 0 except Exception as e: logger.warning(f"Get class d id error: {e}", exc_info=True) return uid, mid
def config_directly(client: Client, message: Message) -> bool: # Config the bot directly if not message or not message.chat: return True # Basic data gid = message.chat.id mid = message.message_id try: # Check permission if not is_class_c(None, None, message): return True aid = message.from_user.id success = True reason = lang("config_updated") new_config = deepcopy(glovar.configs[gid]) text = f"{lang('admin_group')}{lang('colon')}{code(aid)}\n" # Check command format command_type, command_context = get_command_context(message) if command_type: if command_type == "show": text += f"{lang('action')}{lang('colon')}{code(lang('config_show'))}\n" text += get_config_text(new_config) thread(send_report_message, (30, client, gid, text)) return True now = get_now() if now - new_config["lock"] > 310: if command_type == "default": new_config = deepcopy(glovar.default_config) else: if command_context: if command_type in {"delete", "mention"}: if command_context == "off": new_config[command_type] = False elif command_context == "on": new_config[command_type] = True else: success = False reason = lang("command_para") elif command_type == "limit": limit = get_int(command_context) if 2 <= limit <= 5: new_config["limit"] = limit else: success = False reason = lang("command_para") elif command_type == "report": if not new_config.get("report"): new_config["report"] = {} if command_context == "off": new_config["report"]["auto"] = False new_config["report"]["manual"] = False elif command_context == "auto": new_config["report"]["auto"] = True new_config["report"]["manual"] = False elif command_context == "manual": new_config["report"]["auto"] = False new_config["report"]["manual"] = True elif command_context == "both": new_config["report"]["auto"] = True new_config["report"]["manual"] = True else: success = False reason = lang("command_para") else: success = False reason = lang("command_type") else: success = False reason = lang("command_lack") if success: new_config["default"] = False else: success = False reason = lang("config_locked") else: success = False reason = lang("command_usage") if success and new_config != glovar.configs[gid]: # Save new config glovar.configs[gid] = new_config save("configs") # Send debug message debug_text = get_debug_text(client, message.chat) debug_text += ( f"{lang('admin_group')}{lang('colon')}{code(message.from_user.id)}\n" f"{lang('action')}{lang('colon')}{code(lang('config_change'))}\n" f"{lang('more')}{lang('colon')}{code(f'{command_type} {command_context}')}\n" ) thread(send_message, (client, glovar.debug_channel_id, debug_text)) text += ( f"{lang('action')}{lang('colon')}{code(lang('config_change'))}\n" f"{lang('status')}{lang('colon')}{code(reason)}\n") thread(send_report_message, ((lambda x: 10 if x else 5)(success), client, gid, text)) return True except Exception as e: logger.warning(f"Config directly error: {e}", exc_info=True) finally: delete_message(client, gid, mid) return False
def report_answer(client: Client, message: Message, gid: int, aid: int, mid: int, action_type: str, key: str, reason: str = None) -> str: # Answer the user's report try: report_record = glovar.reports.get(key) if not report_record: message_text = get_text(message) uid = get_int(message_text.split("\n")[0].split(lang("colon"))[1]) text = ( f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n" f"{lang('reason')}{lang('colon')}{code(lang('expired'))}\n") thread(edit_message_text, (client, gid, mid, text)) delay(15, delete_message, [client, gid, mid]) glovar.user_ids[uid]["waiting"].discard(gid) save("user_ids") return "" if not report_record["time"]: return "" rid = report_record["reporter_id"] uid = report_record["user_id"] r_mid = report_record["message_id"] record_reason = report_record["reason"] if not reason: reason = record_reason if not (init_user_id(rid) and init_user_id(uid)): return "" # Check users' locks if gid in glovar.user_ids[uid]["lock"] or gid in glovar.user_ids[rid][ "lock"]: return lang("answer_proceeded") # Lock the report status glovar.reports[key]["time"] = 0 try: if action_type == "ban": text, markup = ban_user(client, message, uid, aid, 0, reason) thread(delete_message, (client, gid, r_mid)) elif action_type == "warn": text, markup = warn_user(client, message, uid, aid, reason) thread(delete_message, (client, gid, r_mid)) elif action_type == "abuse": if not rid: return "" message.reply_to_message.from_user.id = rid message.reply_to_message.from_user.is_self = lang( "abuse_report") text, markup = warn_user(client, message, rid, aid) text += f"{lang('reason')}{lang('colon')}{code(lang('reason_abuse'))}\n" else: reported_link = general_link( r_mid, f'{get_channel_link(message)}/{r_mid}') if rid: reporter_text = code(rid) else: reporter_text = code(lang("auto_triggered")) text = ( f"{lang('reported_user')}{lang('colon')}{mention_id(uid)}\n" f"{lang('reported_message')}{lang('colon')}{reported_link}\n" f"{lang('reporter')}{lang('colon')}{reporter_text}\n" f"{lang('action')}{lang('colon')}{code(lang('action_cancel'))}\n" f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n" f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n" ) markup = None if markup: secs = 180 else: secs = 15 thread(edit_message_text, (client, gid, mid, text, markup)) delay(secs, delete_message, [client, gid, mid]) finally: glovar.user_ids[uid]["lock"].discard(gid) glovar.user_ids[rid]["lock"].discard(gid) glovar.user_ids[uid]["waiting"].discard(gid) glovar.user_ids[rid]["waiting"].discard(gid) save("user_ids") except Exception as e: logger.warning(f"Report answer error: {e}", exc_info=True) return ""
# Config session app = Client( session_name="bot", ipv6=glovar.ipv6, bot_token=glovar.bot_token, workdir=glovar.SESSION_DIR_PATH, config_file=glovar.CONFIG_PATH, sleep_threshold=0 ) app.start() # Start the bot delay(10, restart_program, [app, glovar.creator_id]) # Start update sleep(glovar.interval) interval_sec_n(app) # Timer scheduler = BackgroundScheduler(job_defaults={"misfire_grace_time": 60}) scheduler.add_job(interval_min_10, "interval", minutes=10) scheduler.add_job(log_rotation, "cron", hour=23, minute=59) scheduler.add_job(restart_program, "cron", [app], hour=glovar.restart, minute=get_int(glovar.restart_text)) scheduler.start() # Hold idle() # Stop app.stop()