Merge pull request 'main' (#1) from bioeb_org/ub4tg:main into main

Reviewed-on: S1S13AF7/ub4tg#1
This commit is contained in:
S1S13AF7 2024-12-14 18:26:06 +02:00
commit 300250b308
3 changed files with 255 additions and 10 deletions

View file

@ -1,7 +1,7 @@
# requirements.txt # requirements.txt
loguru
aiohttp==3.9.0b0 aiohttp==3.9.0b0
aiogram
Telethon-Mod Telethon-Mod
#aiosqlite #aiosqlite
asyncio asyncio

6
run Executable file
View file

@ -0,0 +1,6 @@
#!/bin/sh
if [ -d "venv" ]; then
. venv/bin/activate && python3 ubot.py
else
python3 ubot.py
fi

255
ubot.py
View file

@ -8,6 +8,7 @@ from telethon import TelegramClient, events, utils
from telethon import functions, types from telethon import functions, types
import sys import sys
import os
import json import json
import re import re
import random import random
@ -23,10 +24,55 @@ from collections import Counter
logger.remove() logger.remove()
logger.level("DEBUG", color='<magenta>') logger.level("DEBUG", color='<magenta>')
logger.add(sys.stderr, level="DEBUG") logger.add(sys.stderr, level="DEBUG")
is_termux = os.environ.get('TERMUX_APP__PACKAGE_NAME')
if is_termux:
logger.info('Termux detected, checking permissions...')
logger.info('If you want prevent killing termux by android, get wake lock: check your notifications, find termux app and press "ACQUIRE WAKELOCK"')
logger.warning('This can cause battery drain!')
if os.environ.get('TERMUX_APP__APK_RELEASE') not in ('F_DROID', 'GITHUB'):
logger.warning('You use not f-droid/github apk release, it may have problems...')
logger.warning('F-droid termux release here: https://f-droid.org/en/packages/com.termux/')
logger.warning('Github termux release here: https://github.com/termux/termux-app/releases')
if int(os.environ.get('TERMUX_APP__APP_VERSION_CODE')) < 118:
logger.warning('You use old version of termux, highly recommended that you update to v0.118.0 or higher ASAP for various bug fixes, including a critical world-readable vulnerability')
if os.access('/sdcard', os.W_OK):
logger.success('permission to write on internal storage allowed')
else:
logger.warning('permission denied to write on internal storage')
logger.info('trying get permission...')
os.system('termux-setup-storage')
logger.info('Restart termux [Press CTRL+D or command "exit"]')
sys.exit(0)
# Название сессии # Название сессии
sessdb = 'tl-ub' sessdb = 'tl-ub'
with open("config.json", "r") as configfile: default_directory = ''
default_config_file_path = 'config.json'
treat_as_true = ('true', '1', 't', 'y', 'yes', 'yeah', 'yup', 'certainly', 'uh-huh')
if is_termux:
default_directory = '/sdcard/ub4tg'
os.system(f'mkdir -p {default_directory}')
default_config_file_path = f'{default_directory}/config.json'
if not os.path.exists(default_config_file_path):
logger.info('config not found, first launch setup...')
api_id = int(input('enter api_id from https://my.telegram.org/ : '))
api_hash = input('enter api_hash from https://my.telegram.org/ : ')
timezone = input('enter timezone, format is Country/City: ')
db_pymysql = False
db_sqlite3 = True
a_h = input('enable automatic use medkit? [y/n]: ').lower() in treat_as_true
a_404_patient = input('enable automatic bioeb if victim not found or expired? It will be trigger on "Жертва не найдена" [y/n]: ').lower() in treat_as_true
new_config = {'api_id': api_id,
'api_hash': api_hash,
'timezone': timezone,
'db_pymysql': db_pymysql,
'db_sqlite3': db_sqlite3,
'a_h': a_h,
'a_404_patient': a_404_patient}
with open(default_config_file_path, "w") as configfile:
json.dump(new_config, configfile, indent=4)
with open(default_config_file_path, "r") as configfile:
from types import SimpleNamespace from types import SimpleNamespace
cnf_dict = json.load(configfile) cnf_dict = json.load(configfile)
config = SimpleNamespace(**cnf_dict) config = SimpleNamespace(**cnf_dict)
@ -49,7 +95,7 @@ class states:
auto_bioeb_min_interval = (0.666, 3.666) # for fast leak pathogen auto_bioeb_min_interval = (0.666, 3.666) # for fast leak pathogen
auto_bioeb_max_interval = (71, 121) # waiting for more pathogen auto_bioeb_max_interval = (71, 121) # waiting for more pathogen
# Default strategy mean: you have 4-5 pathogens when auto bioeb is enabled, pathogen overflow reduced # Default strategy mean: you have 4-5 pathogens when auto bioeb is enabled, pathogen overflow reduced
auto_bioeb_stop = False auto_bioeb_stop = True
where_send_check_avocado = None where_send_check_avocado = None
last_sent_bioeb = 0 # for measure time between reply avocado and bioeb last_sent_bioeb = 0 # for measure time between reply avocado and bioeb
last_reply_bioeb_avocado = 0 # same as above last_reply_bioeb_avocado = 0 # same as above
@ -115,6 +161,10 @@ async def main():
con.commit() con.commit()
if db_sqlite3: if db_sqlite3:
logger.debug('sqlite3 database connecting...')
if is_termux:
conn = sqlite3.connect(f"{default_directory}/{my_id}.sqlite")
else:
conn = sqlite3.connect(f"{my_id}.sqlite") # покласти базу рядом? conn = sqlite3.connect(f"{my_id}.sqlite") # покласти базу рядом?
# conn = sqlite3.connect(f"D:\\Misc\\projects\\Python\\ub4tg_db\\{my_id}.sqlite")#Або повністю # conn = sqlite3.connect(f"D:\\Misc\\projects\\Python\\ub4tg_db\\{my_id}.sqlite")#Або повністю
c = conn.cursor() c = conn.cursor()
@ -136,6 +186,13 @@ async def main():
expr_str VARCHAR NOT NULL DEFAULT 0 expr_str VARCHAR NOT NULL DEFAULT 0
)''') )''')
conn.commit() conn.commit()
c.execute('''CREATE TABLE IF NOT EXISTS avocado_exclude (
user_id INTEGER NOT NULL DEFAULT 0 UNIQUE,
reason VARCHAR
)''')
conn.commit()
logger.debug('sqlite3 database initialized')
#################################################################### ####################################################################
async def get_id(url): async def get_id(url):
@ -193,7 +250,7 @@ async def main():
#################################################################### ####################################################################
@client.on(events.NewMessage(pattern='.*йобнув.*|.*подверг(ла)?.*|.*infected.*|.*сикди.*|.*насрал.*|.*за допомогою довіреності.*|.*by authorization infected.*|.*при помощи анонимуса атаковала.*')) @client.on(events.NewMessage(pattern='.*йобнув.*|.*подверг(ла)?.*|.*infected.*|.*сикди.*|.*насрал.*|.*выебал.*|.*за допомогою довіреності.*|.*by authorization infected.*|.*при помощи анонимуса атаковала.*'))
@logger.catch @logger.catch
async def podverg_a(event): async def podverg_a(event):
logger.debug('bio attack detected') logger.debug('bio attack detected')
@ -243,6 +300,11 @@ async def main():
default_bioexpr_theme, default_bioexpr_theme,
default_infected_days_theme, default_infected_days_theme,
default_pathogen_remaining_theme), default_pathogen_remaining_theme),
# "Сексуальная индустрия" theme
(r'<a href="(tg://openmessage\?user_id=\d+|https://t\.me/\w+)">.*</a> выебал.+<a href="(tg://openmessage\?user_id=\d+|https://t\.me/\w+)">',
r"кончила ([0-9\.\,k]+)",
r' ещё ([0-9\ ]+) д.*',
default_pathogen_remaining_theme),
# UA theme [via trust] # UA theme [via trust]
(r'<a href="(tg://openmessage\?user_id=\d+|https://t\.me/\w+)">.*</a> за допомогою довіреності зазнала зараження.+<a href="(tg://openmessage\?user_id=\d+|https://t\.me/\w+)">', (r'<a href="(tg://openmessage\?user_id=\d+|https://t\.me/\w+)">.*</a> за допомогою довіреності зазнала зараження.+<a href="(tg://openmessage\?user_id=\d+|https://t\.me/\w+)">',
r"([0-9\.\,k]+) біо-ресурса", r"([0-9\.\,k]+) біо-ресурса",
@ -266,6 +328,7 @@ async def main():
) )
if m.sender_id != 6333102398: if m.sender_id != 6333102398:
logger.debug('not avocado infection, skipping')
pass pass
elif len(m.entities) > 1: elif len(m.entities) > 1:
h = utils.sanitize_parse_mode( h = utils.sanitize_parse_mode(
@ -286,6 +349,7 @@ async def main():
u2url = r[0][1] u2url = r[0][1]
u1id = await get_id(u1url) u1id = await get_id(u1url)
u2id = await get_id(u2url) u2id = await get_id(u2url)
bio_excludes = [x[0] for x in c.execute('select user_id from avocado_exclude').fetchall()]
# print(f'{u1url} [@{u1id}] подверг(ла) {u2url} [@{u2id}]')#показать # print(f'{u1url} [@{u1id}] подверг(ла) {u2url} [@{u2id}]')#показать
when = int(datetime.timestamp(m.date)) when = int(datetime.timestamp(m.date))
days = int(re.findall(bio_attack_themes[trying_theme_index][2], t)[ days = int(re.findall(bio_attack_themes[trying_theme_index][2], t)[
@ -331,7 +395,7 @@ async def main():
except Exception as Err: except Exception as Err:
logger.exception(f'err: {Err} avocado') logger.exception(f'err: {Err} avocado')
states.last_reply_bioeb_avocado = time.time() states.last_reply_bioeb_avocado = time.time()
if db_sqlite3 and u1id != my_id: if db_sqlite3 and u1id != my_id and u2id not in bio_excludes:
try: try:
c.execute("INSERT INTO avocado(user_id,when_int,bio_str,bio_int,expr_int) VALUES (?, ?, ?, ?, ?)", ( c.execute("INSERT INTO avocado(user_id,when_int,bio_str,bio_int,expr_int) VALUES (?, ?, ?, ?, ?)", (
int(u2id), int(when), str(experience), int(exp_int), 0)) int(u2id), int(when), str(experience), int(exp_int), 0))
@ -371,11 +435,16 @@ async def main():
else: else:
logger.info( logger.info(
f'''{u1url} [@{u1id}] подверг(ла) {u2url} [@{u2id}] +{experience}, d: {days}''') f'''{u1url} [@{u1id}] подверг(ла) {u2url} [@{u2id}] +{experience}, d: {days}''')
if u2id in bio_excludes:
logger.debug(f'{u2id} not added: excluded')
#################################################################### ####################################################################
@client.on(events.NewMessage(outgoing=True, pattern=r'\.biofuck$')) @client.on(events.NewMessage(outgoing=True, pattern=r'\.biofuck$'))
async def cmd_bf(event): # крч акуратно з цим,вдруг шо я нічо async def cmd_bf(event): # крч акуратно з цим,вдруг шо я нічо
if states.auto_bioeb_stop is False:
await event.edit('biofucking already runned!')
return
m = event.message m = event.message
when = int(datetime.timestamp(m.date)) when = int(datetime.timestamp(m.date))
msg = '🤷' # якщо нема кого то жри рандом. msg = '🤷' # якщо нема кого то жри рандом.
@ -383,9 +452,15 @@ async def main():
def get_some_patients(limit=1000): def get_some_patients(limit=1000):
count = int(c.execute( count = int(c.execute(
f"SELECT COUNT(*) FROM `avocado` WHERE expr_int <= {when} ORDER BY expr_int,when_int ASC LIMIT {limit}").fetchone()[0]) f"SELECT COUNT(*) FROM `avocado` WHERE expr_int <= {when} ORDER BY expr_int,when_int ASC LIMIT {limit}").fetchone()[0])
c.execute( patients = list(c.execute(
f"SELECT * FROM `avocado` WHERE expr_int <= {when} ORDER BY expr_int,when_int ASC LIMIT {limit}") f"SELECT * FROM `avocado` WHERE expr_int <= {when} ORDER BY expr_int,when_int ASC LIMIT {limit}").fetchall())
return count, list(c.fetchall()) bio_excludes = [x[0] for x in c.execute('select user_id from avocado_exclude').fetchall()]
for p in patients:
if p[0] in bio_excludes:
logger.warning(f'skipping patient {p[0]}, excluded from bioebinng')
patients.remove(p)
return count, patients
count, e_info = get_some_patients() count, e_info = get_some_patients()
# more random for random and reduce risk get very immun target after restart # more random for random and reduce risk get very immun target after restart
@ -452,6 +527,170 @@ async def main():
states.auto_bioeb_stop = True states.auto_bioeb_stop = True
await event.edit('Trying stop...') # ред await event.edit('Trying stop...') # ред
@client.on(events.NewMessage(outgoing=True, pattern=r'\.bioexclude'))
async def add_bioeb_exclude(event):
reason = event.text.split(' ', 1)[1] or None
reply = await client.get_messages(event.peer_id, ids=event.reply_to.reply_to_msg_id)
if not reply.entities:
await event.edit('ids not found')
return
t = reply.raw_text
h = utils.sanitize_parse_mode(
'html').unparse(t, reply.entities) # HTML
r = re.findall(r'<a href="(tg://openmessage\?user_id=\d+|https://t\.me/\w+)">', h)
insertion_status = []
for link in r:
user_id = await get_id(link)
try:
c.execute("INSERT INTO avocado_exclude(user_id, reason) VALUES (?, ?)", (user_id, reason))
insertion_status.append(f'{user_id}: ok')
except:
insertion_status.append(f'{user_id}: exists')
conn.commit()
insertion_status = '\n'.join(insertion_status)
await event.edit(f'{insertion_status}\nreason: {reason}')
@client.on(events.NewMessage(outgoing=True, pattern=r'\.bioebmass$'))
async def bioeb_mass(event):
reply = await client.get_messages(event.peer_id, ids=event.reply_to.reply_to_msg_id)
when = int(datetime.timestamp(event.date))
t = reply.raw_text
h = utils.sanitize_parse_mode(
'html').unparse(t, reply.entities) # HTML
r_as_list = []
r = re.findall(r'<a href="(tg://openmessage\?user_id=\d+|https://t\.me/\w+)">|(@\d+)', h)
for x in r:
r_as_list.extend(x)
r = r_as_list
if r == []:
await event.edit('nothing to do: ids not found')
return
def filter_bioeb(victims_ids):
bio_excludes = [x[0] for x in c.execute('SELECT user_id FROM avocado_exclude').fetchall()]
filted_victims = []
for v in victims_ids:
if v in bio_excludes:
logger.warning(f'skipping patient {v}, excluded from bioebinng')
elif c.execute(f'SELECT user_id FROM avocado WHERE expr_int >= {when} and user_id == {v}').fetchone():
logger.warning(f'skipping patient {v}, already eaten')
else:
filted_victims.append(v)
return list(set(filted_victims))
bioebbing_ids = []
for i in r:
if i == '':
continue
if i.startswith('@'):
bioebbing_ids.append(int(i.replace('@', '')))
else:
bioebbing_ids.append(await get_id(i))
bioebbing_ids = filter_bioeb(bioebbing_ids)
bioebbing_len = len(bioebbing_ids)
if bioebbing_len == 0:
await event.edit('already eaten or excluded')
return
await event.edit(f'trying eat {bioebbing_len} patients...')
for patient in bioebbing_ids:
await asyncio.sleep(random.uniform(1.234, 4.222))
await event.respond(f'биоеб {patient}')
@client.on(events.NewMessage(outgoing=True, pattern=r'\.biostealbackup'))
async def bio_steal_backup(event):
cmd = event.text.split(' ', 1)
if len(cmd) > 1:
cmd = cmd[1].lower()
if cmd == 'me':
logger.info('Requested steal yourself backup...')
else:
logger.info('Stealing backup...')
reply = await client.get_messages(event.peer_id, ids=event.reply_to.reply_to_msg_id)
await event.edit('Downloading file...')
file_path = await reply.download_media(file=f"{default_directory}")
logger.success(f'backup file saved to {file_path}')
victims = None
raw_victims = None
file_format = None
with open(file_path, 'r') as stealed_backup:
if file_path.lower().endswith('.json'):
victims = json.load(stealed_backup)
file_format = 'json'
await event.edit('Processing json victims...')
elif file_path.lower().endswith('.txt'):
raw_victims = stealed_backup.readlines()
file_format = 'txt'
await event.edit('Processing raw txt victims...')
else:
await event.edit('Format not supported, avalaible: txt, json')
return
added = 0
rejected = 0
my_victims_ids = []
if file_format == 'json':
for v in victims:
user_id = int(v['user_id'])
profit = v['profit']
when = v['from_infect']
expr = v['until_infect']
if cmd == 'me':
my_victims_ids.append(user_id)
c.execute("INSERT OR REPLACE INTO avocado(user_id,when_int,bio_str,bio_int,expr_int) VALUES (?, ?, ?, ?, ?)",
(int(user_id), int(when), str(profit), int(profit), int(expr)))
added += 1
else:
if not c.execute(f'SELECT user_id FROM avocado WHERE user_id == {user_id}').fetchone() and not c.execute(f'SELECT user_id FROM avocado_exclude WHERE user_id == {user_id}').fetchone():
c.execute("INSERT INTO avocado(user_id,when_int,bio_str,bio_int,expr_int) VALUES (?, ?, ?, ?, ?)",
(int(user_id), int(when), str(profit), int(profit), 0))
added += 1
else:
rejected += 1
elif file_format == 'txt':
when = int(datetime.timestamp(event.date))
for raw_v in raw_victims:
if raw_v == '':
continue
user_id = re.findall(r'tg://openmessage\?user_id=(\d+)', raw_v)
if not user_id:
continue
user_id = int(user_id[0])
profit = re.findall(r'([0-9\.\,k]+) опыта', raw_v)
if not profit:
continue
profit = profit[0]
if ',' in profit:
profit = re.sub(r',', r'.', profit)
if 'k' in profit:
profit_int = int(
float(re.sub('k', '', profit)) * 1000)
else:
profit_int = int(profit)
if not c.execute(f'SELECT user_id FROM avocado WHERE user_id == {user_id}').fetchone() and not c.execute(f'SELECT user_id FROM avocado_exclude WHERE user_id == {user_id}').fetchone():
c.execute("INSERT INTO avocado(user_id,when_int,bio_str,bio_int,expr_int) VALUES (?, ?, ?, ?, ?)",
(int(user_id), int(when), str(profit), int(profit_int), 0))
added += 1
logger.debug(f'added {user_id} - {profit_int}')
else:
rejected += 1
conn.commit()
logger.success('backup success stealed')
if cmd == 'me':
my_victims_ids = tuple(my_victims_ids)
result = c.execute(f'UPDATE avocado SET expr_int = 0 WHERE user_id NOT IN {my_victims_ids}').fetchall()
conn.commit()
logger.success('database rebased')
del my_victims_ids
del victims # free memory
del raw_victims
if cmd == 'me':
rebased = len(result)
await event.edit(f'Success added/updated {added} patients\nOther {rebased} patients reset to 0')
del result
else:
await event.edit(f'Success added {added} new patients\nRejected or exists: {rejected}')
@client.on(events.NewMessage(outgoing=True, pattern=r'\.biocheck$')) @client.on(events.NewMessage(outgoing=True, pattern=r'\.biocheck$'))
async def set_default_check_chat(event): async def set_default_check_chat(event):
states.where_send_check_avocado = event.peer_id states.where_send_check_avocado = event.peer_id
@ -483,7 +722,7 @@ async def main():
#################################################################### ####################################################################
@client.on(events.NewMessage(pattern='🚫 Жертва не найдена')) @client.on(events.NewMessage(pattern='⏱?🚫 Жертва'))
async def infection_not_found(event): async def infection_not_found(event):
m = event.message m = event.message
if m.sender_id != 6333102398: if m.sender_id != 6333102398: