import discord from time import sleep intents = discord.Intents.default() intents.message_content = True bot = discord.Client(intents=intents) # API для отправки сообщения о переводе # TG -> DS / DS -> Mine / ... from fastapi import FastAPI, HTTPException from pydantic import BaseModel import uvicorn app = FastAPI() # Для запуска API в потоке from threading import Thread from call2api import * from db import * API_TOKEN = read('conf.json')['api_token'] DS_TOKEN = read('conf.json')['ds_token'] from datetime import datetime LCTIME = datetime.now() # Обнуляем данные db = read('conf.json') db['push_src_nick'] = 0 db['push_id'] = 0 db['push_amount'] = 0 write(db, 'conf.json') # Поток для приёма входящих переводов ТГ-ДС (костыль) from discord.ext import tasks @tasks.loop(seconds = 0.1) async def push(): db = read('conf.json') if db['push_id'] != 0: src_nick, id, amount = db['push_src_nick'], db['push_id'], db['push_amount'] user = await bot.fetch_user(id) await user.send(f'''Вам перевели `{amount}` CDM. Отправитель: `{src_nick}`''') db['push_src_nick'], db['push_id'], db['push_amount'] = 0, 0, 0 write(db, 'conf.json') @bot.event async def on_ready(): print(f'We have logged in as {bot.user}') await push.start() return 0 async def checkauth(message, reg = False): send = message.channel.send if user_in_db(API_TOKEN, ds=message.author.id) != 'false': return True elif reg: pass else: await send('''Пожалуйста, зарегистрируйтесь или войдите: `/reg Nickname 1234567890` `/login Nickname 1234567890` Ник вводить желательно игровой. Пароль любой.''') def command(com, message): # Если не бот if message.author != bot.user: # Если не публичный чат if message.channel.type != discord.ChannelType.text: if message.content.startswith(f'/{com}'): return True async def help(message): send = message.channel.send await send('''Исходный код: https://gitea.del.pw/justuser/CryptoDM Доступные команды: `/help - Помощь /reg ник - Регистрация /login ник пароль - Войти в аккаунт /unreg - Выйти из аккаунта /passwd пароль - Смена пароля /nick ник - Смена ника /bal - Баланс /pay ник сумма - Перевод /time2cdm - Конвертация времени на сервере в CDM /stats - Статистика ` ''') async def bal(message): send = message.channel.send if await checkauth(message): id = user_in_db(API_TOKEN, ds=message.author.id) coins = check_bal(API_TOKEN, id) nick = get_nick(API_TOKEN, id) time = int(get_time(API_TOKEN, id)) hours = time//3600 ; minutes = (time - hours*3600)//60 await send(f'''Ваш баланс: `{coins}` CDM Время на сервере: `{f"{hours}:{minutes}"}` Ник: `{nick}`''') async def reg(message): send = message.channel.send if not await checkauth(message, reg=True): global LCTIME time_delta = datetime.now() - LCTIME if time_delta.seconds < 1: await send('Большая нагрузка, повторите запрос позже...') return 0 if len(message.content.split()) == 3: com, nick, passwd = message.content.split() # Проверяем нет ли такого же ника if user_in_db(API_TOKEN, nick=nick) == 'false': if user_add(API_TOKEN, nick, passwd, ds=message.author.id) == 'OK': await send('Вы успешно зарегистрированны!') else: await send('Что-то пошло не так...') else: await send('Уже существует пользователь с таким ником') else: await send('/reg ник пароль') else: await send('Вы уже зарегистрированны') async def login(message): send = message.channel.send if len(message.content.split()) == 3: global LCTIME time_delta = datetime.now() - LCTIME if time_delta.seconds < 1: await send('Большая нагрузка, повторите запрос позже...') return 0 com, nick, passwd = message.content.split() id = user_in_db(API_TOKEN, nick=nick) if get_ds(API_TOKEN, id) != 'null': await send('Этот пользователь уже авторизован') elif get_passwd(API_TOKEN, id) == hash(passwd): if update_ds(API_TOKEN, id, ds=message.author.id) == 'OK': await send('Вы успешно авторизовались!') else: await send('Что-то пошло не так...') else: await send('Пароль не совпадает') else: await send('/login ник пароль') async def unreg(message): send = message.channel.send id = user_in_db(API_TOKEN, ds=message.author.id) if update_ds(API_TOKEN, id, 'None') == 'OK': await send('Вы успешно вышли из аккаунта') async def passwd(message): send = message.channel.send if await checkauth(message): if len(message.content.split()) == 2: com, passwd = message.content.split() id = user_in_db(API_TOKEN, ds=message.author.id) if update_passwd(API_TOKEN, id, passwd) == 'OK': await send('Пароль успешно изменён.') else: await send('Что-то пошло не так...') else: await send('/passwd пароль') async def nick(message): send = message.channel.send if await checkauth(message): if len(message.content.split()) == 2: com, nicl = message.content.split() id = user_in_db(API_TOKEN, ds=message.author.id) if update_nick(API_TOKEN, id, new_nick) == 'OK': await send('Ник успешно изменён') else: await send('Что-то пошло не так...') else: await send('/nick ник') async def pay(message): send = message.channel.send if await checkauth(message): if len(message.content.split()) == 3: com, nick, amount = message.content.split() if float(amount) <= 0.0001: await send('Слишком малое или недопустимое значение.') return 0 amount = str(float(amount)) # Защиты от 1000 нулей в начале src_id = user_in_db(API_TOKEN, ds=message.author.id) dst_id = user_in_db(API_TOKEN, nick=nick) if dst_id == 'false': await send('Не существует такого пользователя.') else: status = coins_transfer(API_TOKEN, src_id, dst_id, amount) if status == 'No_money': await send('Недостаточно средств.') elif status == 'OK': await send(f'''Успешно переведено `{amount}` CDM. Адресат: `{nick}`''') ds_dst = get_ds(API_TOKEN, dst_id) tg_dst = get_tg(API_TOKEN, dst_id) src_nick = get_nick(API_TOKEN, src_id) if ds_dst != 'null': transfer_callback('http://127.0.0.1:3333/', API_TOKEN, src_nick, nick, amount) elif tg_dst != 'null': print(22222) transfer_callback('http://127.0.0.1:2222/', API_TOKEN, src_nick, nick, amount) else: await send('/pay ник количество') async def time2cdm(message): send = message.channel.send if await checkauth(message): id = user_in_db(API_TOKEN, ds=message.author.id) course = read('conf.json')['time2cdm'] time = int(get_time(API_TOKEN, id)) amount = time*course if update_time(API_TOKEN, id, '0'): if coins_add(API_TOKEN, id, str(amount)): await send(f'''Вы успешно конвертировали время на сервере в `{str(amount)}` CDM.''') async def stats(message): send = message.channel.send if await checkauth(message): data = get_stat(API_TOKEN) bal = f'Баланс ({data["gbal_delta"]})' t2cdm = f'Time2cdm ({data["time2cdm_delta"]})' max_len = max(len(bal), len(t2cdm), 19) await send(f'''```json {bal.ljust(max_len)}: {data["gbal"]} {t2cdm.ljust(max_len)}: {data["time2cdm"]} Среднее значение : {data["average"]} Медиана : {data["median"]} Минимум : {data["min"]} Максимум : {data["max"]} Ввод/вывод алмазов : {data["up_diamond"]} ``` ''') @bot.event async def on_message(message): send = message.channel.send if command('help', message): await help(message) elif command('reg', message): await reg(message) elif command('login', message): await login(message) elif command('unreg', message): await unreg(message) elif command('bal', message): await bal(message) elif command('passwd', message): await passwd(message) elif command('pay', message): await pay(message) elif command('time2cdm', message): await time2cdm(message) elif command('stats', message): await stats(message) # API для переводов TG->DS / ... class Transfer_callback_api(BaseModel): token: str src_nick: str dst_nick: str amount: str @app.post('/api/transfer_callback/') def transfer_callback_api(it: Transfer_callback_api): token, src_nick, dst_nick, amount = it.token, it.src_nick, it.dst_nick, it.amount db = read() if token in db['tokens']: dst_id = user_in_db(API_TOKEN, nick=dst_nick) ds_dst = int(get_ds(API_TOKEN, id=dst_id)) # Передаём в поток данные (см начало скрипта) db = read('conf.json') db['push_src_nick'] = src_nick db['push_id'] = ds_dst db['push_amount'] = amount write(db, 'conf.json') return 200 else: return 'Error' def run_api(): uvicorn.run(app, host='127.0.0.1', port=7003) # Запускаем API для переводов api = Thread(target=run_api) api.Daemon = True api.start() # Запускаем бота bot.run(DS_TOKEN)