On branch main
Your branch is up to date with 'origin/main'. hanges to be committed: modified: controller.py Untracked files: __pycache__/ adada_session.session config.json controller_bot.session controller_bot.session-journal farm_state.db honmi_session.session xzorisme1_session.session xzorisme1_session.session-journal xzorisme_session.session xzorisme_session.session-journal
This commit is contained in:
parent
2d61a00498
commit
900090f45e
@ -1,10 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
controller.py — бот через Bot API, которым вы полностью управляете фармом:
|
controller.py — бот через Bot API для управления фарм-аккаунтами.
|
||||||
регистрируете аккаунты (вводите api_id/api_hash/номер/код/пароль 2FA прямо
|
|
||||||
в чате), настраиваете цель/команду/интервал, ставите на паузу и т.д.
|
|
||||||
|
|
||||||
Никакого ручного редактирования JSON с аккаунтами — всё через /addaccount
|
Маскировка кода: каждая цифра кода подтверждения +4 (по модулю 10).
|
||||||
и инлайн-меню.
|
Пример: код 11892 → вводите 55236.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
@ -45,11 +43,34 @@ app = Client(
|
|||||||
|
|
||||||
admin_filter = filters.user(list(ADMIN_IDS)) & filters.private
|
admin_filter = filters.user(list(ADMIN_IDS)) & filters.private
|
||||||
|
|
||||||
# Состояние мастера регистрации: admin_id -> {"step": ..., "data": {...}, "client": Client, "phone_code_hash": ...}
|
# Состояние мастера: admin_id -> {"step": ..., "data": {...}, "client": Client, "phone_code_hash": ...}
|
||||||
pending = {}
|
pending = {}
|
||||||
|
|
||||||
|
# Маскировка кода: каждая цифра +4 (6→0, 7→1, 8→2, 9→3)
|
||||||
|
CODE_OFFSET = 4
|
||||||
|
|
||||||
|
|
||||||
|
def encode_code(code: str) -> str:
|
||||||
|
"""Кодирует код: каждая цифра +4 по модулю 10."""
|
||||||
|
masked = ""
|
||||||
|
for digit in code:
|
||||||
|
if digit.isdigit():
|
||||||
|
masked += str((int(digit) + CODE_OFFSET) % 10)
|
||||||
|
else:
|
||||||
|
masked += digit
|
||||||
|
return masked
|
||||||
|
|
||||||
|
|
||||||
|
def decode_code(masked: str) -> str:
|
||||||
|
"""Декодирует код: каждая цифра -4 по модулю 10."""
|
||||||
|
code = ""
|
||||||
|
for digit in masked:
|
||||||
|
if digit.isdigit():
|
||||||
|
code += str((int(digit) - CODE_OFFSET) % 10)
|
||||||
|
else:
|
||||||
|
code += digit
|
||||||
|
return code
|
||||||
|
|
||||||
# ---------- вспомогательное ----------
|
|
||||||
|
|
||||||
def fmt_eta(state):
|
def fmt_eta(state):
|
||||||
if not state["target_chat"] or not state["farm_command"]:
|
if not state["target_chat"] or not state["farm_command"]:
|
||||||
@ -98,7 +119,8 @@ async def start_cmd(client, message: Message):
|
|||||||
"/setcommand <name> <команда>\n"
|
"/setcommand <name> <команда>\n"
|
||||||
"/farmnow <name>\n"
|
"/farmnow <name>\n"
|
||||||
"/removeaccount <name>\n"
|
"/removeaccount <name>\n"
|
||||||
"/cancel — отменить текущий мастер",
|
"/cancel — отменить текущий мастер\n\n"
|
||||||
|
"🔐 Код подтверждения вводится ЗАМАСКИРОВАННЫМ: каждая цифра +4 (6→0, 7→1, 8→2, 9→3).",
|
||||||
reply_markup=main_menu(),
|
reply_markup=main_menu(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -297,7 +319,7 @@ async def addaccount_cmd(client, message: Message):
|
|||||||
async def flow_router(client, message: Message):
|
async def flow_router(client, message: Message):
|
||||||
admin_id = message.from_user.id
|
admin_id = message.from_user.id
|
||||||
if admin_id not in pending:
|
if admin_id not in pending:
|
||||||
return # не в мастере — игнорируем, чтобы не мешать обычной переписке
|
return # не в мастере — игнорируем
|
||||||
state = pending[admin_id]
|
state = pending[admin_id]
|
||||||
step = state["step"]
|
step = state["step"]
|
||||||
text = message.text.strip()
|
text = message.text.strip()
|
||||||
@ -357,12 +379,19 @@ async def flow_router(client, message: Message):
|
|||||||
state["phone_code_hash"] = sent.phone_code_hash
|
state["phone_code_hash"] = sent.phone_code_hash
|
||||||
state["step"] = "code"
|
state["step"] = "code"
|
||||||
await message.reply(
|
await message.reply(
|
||||||
"Код отправлен в Telegram на этот номер (или SMS). "
|
"Код отправлен в Telegram app/SMS.\n\n"
|
||||||
"Введите код одной строкой, без пробелов:"
|
"🔐 *ЗАМАСКИРУЙТЕ КОД ПЕРЕД ОТПРАВКОЙ:*\n"
|
||||||
|
"Каждую цифру кода увеличьте на 4:\n"
|
||||||
|
"0→4, 1→5, 2→6, 3→7, 4→8, 5→9, 6→0, 7→1, 8→2, 9→3\n\n"
|
||||||
|
"Пример: код `11892` → введите `55236`\n\n"
|
||||||
|
"Введите замаскированный код:"
|
||||||
)
|
)
|
||||||
|
|
||||||
elif step == "code":
|
elif step == "code":
|
||||||
code = text.replace(" ", "")
|
# Декодируем замаскированный код
|
||||||
|
masked_code = text.replace(" ", "")
|
||||||
|
code = decode_code(masked_code)
|
||||||
|
|
||||||
tg_client = state["client"]
|
tg_client = state["client"]
|
||||||
try:
|
try:
|
||||||
await tg_client.sign_in(data["phone"], state["phone_code_hash"], code)
|
await tg_client.sign_in(data["phone"], state["phone_code_hash"], code)
|
||||||
@ -371,7 +400,7 @@ async def flow_router(client, message: Message):
|
|||||||
await message.reply("Включена двухфакторная защита (2FA). Введите пароль:")
|
await message.reply("Включена двухфакторная защита (2FA). Введите пароль:")
|
||||||
return
|
return
|
||||||
except (PhoneCodeInvalid, PhoneCodeExpired):
|
except (PhoneCodeInvalid, PhoneCodeExpired):
|
||||||
await message.reply("Неверный или просроченный код. Введите код ещё раз или /cancel:")
|
await message.reply("Неверный или просроченный код. Введите замаскированный код ещё раз или /cancel:")
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await message.reply(f"Ошибка входа: {e}\nПрервано, начните заново: /addaccount")
|
await message.reply(f"Ошибка входа: {e}\nПрервано, начните заново: /addaccount")
|
||||||
@ -425,7 +454,6 @@ async def flow_router(client, message: Message):
|
|||||||
del pending[admin_id]
|
del pending[admin_id]
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
# страхуемся от любых неожиданных ошибок мастера, чтобы не зависнуть в pending навсегда
|
|
||||||
await cancel_flow(admin_id)
|
await cancel_flow(admin_id)
|
||||||
await message.reply("Что-то пошло не так, мастер прерван. Попробуйте /addaccount заново.")
|
await message.reply("Что-то пошло не так, мастер прерван. Попробуйте /addaccount заново.")
|
||||||
|
|
||||||
@ -434,7 +462,7 @@ async def finish_login(admin_id, message: Message):
|
|||||||
state = pending[admin_id]
|
state = pending[admin_id]
|
||||||
tg_client = state["client"]
|
tg_client = state["client"]
|
||||||
me = await tg_client.get_me()
|
me = await tg_client.get_me()
|
||||||
await tg_client.disconnect() # сессия сохранена на диске, дальше её использует farmer.py
|
await tg_client.disconnect()
|
||||||
state["step"] = "target"
|
state["step"] = "target"
|
||||||
await message.reply(
|
await message.reply(
|
||||||
f"Успешный вход как {me.first_name} (@{me.username or 'без юзернейма'}).\n"
|
f"Успешный вход как {me.first_name} (@{me.username or 'без юзернейма'}).\n"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user