diff --git a/api.py b/api.py new file mode 100644 index 0000000..992f527 --- /dev/null +++ b/api.py @@ -0,0 +1,333 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel + +from db import * + +app = FastAPI() + +def token_check(token): + db = read() + if token in db['tokens']: + return True + else: + return False + +class User_in_db(BaseModel): + token: str + id: str = None + tg: str = None + ds: str = None + mine: str = None + nick: str = None +@app.post('/api/user_in_db/') +def user_in_db(it: User_in_db): + token, id, tg, ds, mine, nick = it.token, it.id, it.tg, it.ds, it.mine, it.nick + if token_check(token): + db = read() + try: + if id and id in db['id']: + return id + elif tg and tg in db['tg']: + return db['tg'][tg] + elif ds and ds in db['ds']: + return db['ds'][ds] + elif mine and mine in db['mine']: + return db['mine'][mine] + elif nick and nick in db['nick']: + return db['nick'][nick] + else: + return False + except: + return False + else: + return 'Error' + + +def gen_id(): + db = read() + for i in range(1,100000): + check = str(i) + print(db) + if check not in db['id']: + return str(i) + return 'Full?' + +class User_add(BaseModel): + token: str + id: str = None + tg: str = None + ds: str = None + mine: str = None + nick: str + passwd: str +@app.post('/api/user_add/') +def user_add(it: User_add): + token, id, tg, ds, mine, nick, passwd = it.token, it.id, it.tg, it.ds, it.mine, it.nick, it.passwd + id = gen_id() + print(id) + if token_check(token): + db = read() + db['id'][id] = {'tg': tg, 'ds': ds, 'mine': mine, 'nick': nick, 'passwd': passwd, 'bal': 0.0} + db['nick'][nick] = id + if tg: + db['tg'][tg] = id + if ds: + db['ds'][ds] = id + if mine: + db['mine'][mine] = id + write(db) + return 'OK' + else: + return 'Error' + +class User_del(BaseModel): + token: str + id: str +@app.post('/api/user_del/') +def user_del(it: User_del): + token, id = it.token, it.id + if token_check(token): + db = read() + tg, ds, mine, nick = db['id'][id]['tg'], db['id'][id]['ds'], db['id'][id]['mine'], db['id'][id]['nick'] + del db['nick'][nick] + if tg: + del db['tg'][tg] + if ds: + del db['ds'][ds] + if mine: + del db['mine'][mine] + del db['id'][id] + write(db) + return 'OK' + else: + return 'Error' + +class Coins_add(BaseModel): + token: str + id: str + amount: str +@app.post('/api/coins_add/') +def coins_add(it: Coins_add): + token, id, amount = it.token, it.id, float(it.amount) + if token_check(token): + db = read() + db['id'][id]['bal'] += amount + write(db) + return 'OK' + else: + return 'Error' + +class Coins_del(BaseModel): + token: str + id: str + amount: str +@app.post('/api/coins_del/') +def coins_del(it: Coins_del): + token, id, amount = it.token, it.id, float(it.amount) + if token_check(token): + db = read() + db['id'][id]['bal'] -= amount + write(db) + return 'OK' + else: + return 'Error' + +class Coins_transfer(BaseModel): + token: str + src_id: str + dst_id: str + amount: str +@app.post('/api/coins_transfer/') +def coins_transfer(it: Coins_transfer): + token, src_id, dst_id, amount = it.token, it.src_id, it.dst_id, float(it.amount) + if token_check(token): + db = read() + amount = abs(amount) # Защита от отриц. чисел + src_bal = db['id'][src_id]['bal'] + if src_bal > amount and amount > 0.0001: + db['id'][src_id]['bal'] -= amount + db['id'][dst_id]['bal'] += amount + write(db) + return 'OK' + else: + return 'No_money' + else: + return 'Error' + +class Update_tg(BaseModel): + token: str + id: str + tg: str +@app.post('/api/update_tg/') +def update_tg(it: Update_tg): + token, id, tg = it.token, it.id, it.tg + if token_check(token): + db = read() + cur_tg = db['id'][id]['tg'] + try: + del db['tg'][cur_tg] + except: + pass + if tg == 'None': + db['id'][id]['tg'] = None + else: + db['id'][id]['tg'] = tg + db['tg'][tg] = id + write(db) + return 'OK' + else: + return 'Error' + +class Update_ds(BaseModel): + token: str + id: str + ds: str +@app.post('/api/update_ds/') +def update_ds(it: Update_ds): + token, id, ds = it.token, it.id, it.ds + if token_check(token): + db = read() + cur_ds = db['id'][id]['ds'] + try: + del db['ds'][cur_ds] + except: + pass + if ds == 'None': + db['id'][id]['ds'] = None + else: + db['id'][id]['ds'] = ds + db['ds'][ds] = id + write(db) + return 'OK' + else: + return 'Error' + +class Update_mine(BaseModel): + token: str + id: str + mine: str +@app.post('/api/update_mine/') +def update_mine(it: Update_mine): + token, id, mine = it.token, it.id, it.mine + if token_check(token): + db = read() + cur_mine = db['id'][id]['mine'] + del db['mine'][cur_mine] + db['id'][id]['mine'] = mine + db['mine'][mine] = id + write(db) + return 'OK' + else: + return 'Error' + +class Update_nick(BaseModel): + token: str + id: str + nick: str +@app.post('/api/update_nick/') +def update_nick(it: Update_nick): + token, id, nick = it.token, it.id, it.nick + if token_check(token): + db = read() + cur_nick = db['id'][id]['nick'] + del db['nick'][cur_nick] + db['id'][id]['nick'] = nick + db['nick'][nick] = id + write(db) + return 'OK' + else: + return 'Error' + +class Update_passwd(BaseModel): + token: str + id: str + passwd: str +@app.post('/api/update_passwd/') +def update_tg(it: Update_passwd): + token, id, passwd = it.token, it.id, it.passwd + if token_check(token): + db = read() + db['id'][id]['passwd'] = passwd + write(db) + return 'OK' + else: + return 'Error' + + +class Check_bal(BaseModel): + token: str + id: str +@app.post('/api/check_bal/') +def check_bal(it: Check_bal): + token, id = it.token, it.id + if token_check(token): + db = read() + return db['id'][id]['bal'] + else: + return 'Error' + +class Get_nick(BaseModel): + token: str + id: str +@app.post('/api/get_nick/') +def get_nick(it: Get_nick): + token, id = it.token, it.id + if token_check(token): + db = read() + return db['id'][id]['nick'] + else: + return 'Error' + +class Get_tg(BaseModel): + token: str + id: str +@app.post('/api/get_tg/') +def get_tg(it: Get_tg): + token, id = it.token, it.id + if token_check(token): + db = read() + return db['id'][id]['tg'] + else: + return 'Error' + +class Get_ds(BaseModel): + token: str + id: str +@app.post('/api/get_ds/') +def get_ds(it: Get_ds): + token, id = it.token, it.id + if token_check(token): + db = read() + return db['id'][id]['ds'] + else: + return 'Error' + +class Get_mine(BaseModel): + token: str + id: str +@app.post('/api/get_mine/') +def get_mine(it: Get_mine): + token, id = it.token, it.id + if token_check(token): + db = read() + return db['id'][id]['mine'] + else: + return 'Error' + +class Get_passwd(BaseModel): + token: str + id: str +@app.post('/api/get_passwd/') +def get_passwd(it: Get_passwd): + token, id = it.token, it.id + if token_check(token): + db = read() + return db['id'][id]['passwd'] + else: + return 'Error' + +# TODO: unauth from account + +if __name__ == '__main__': + import uvicorn + uvicorn.run(app, host='127.0.0.1', port=1111) diff --git a/call2api.py b/call2api.py new file mode 100644 index 0000000..15c3ef1 --- /dev/null +++ b/call2api.py @@ -0,0 +1,111 @@ +from requests import post +from json import dumps +from xxhash import xxh32 + +from db import * + +global url_pre +url_pre = 'http://127.0.0.1:1111/' + +def hash(text): + text = str(text) + return xxh32(text).hexdigest() + +def call(api_url, data): + response = post(url_pre + api_url, data=dumps(data)) + print(response.status_code) + print(response.text) + return response.text.replace('"', '') + +def user_in_db(token, id=None, tg=None, ds=None, mine=None, nick=None): + data = {'token': token} + if id: + data['id'] = id + elif tg: + data['tg'] = str(tg) + elif ds: + data['ds'] = str(ds) + elif mine: + data['mine'] = mine + elif nick: + data['nick'] = nick + #print(data) + return call('api/user_in_db/', data) + +def user_add(token, nick, passwd, tg=None, ds=None, mine=None): + passwd = hash(passwd) + data = {'token': token, 'nick': nick, 'passwd': passwd} + if tg: + data['tg'] = str(tg) + if ds: + data['ds'] = str(ds) + if mine: + data['mine'] = mine + print(data) + return call('api/user_add/', data) + +def user_del(token, id): + data = {'token': token, 'id': id} + return call('api/user_del/', data) + +def coins_add(token, id, amount): + data = {'token': token, 'id': id, 'amount': amount} + return call('api/coins_add/', data) + +def coins_del(token, id, amount): + data = {'token': token, 'id': id, 'amount': amount} + return call('api/coins_del/', data) + +def coins_transfer(token, src_id, dst_id, amount): + data = {'token': token, 'src_id': src_id, 'dst_id': dst_id, 'amount': amount} + return call('api/coins_transfer/', data) + +def update_tg(token, id, tg): + if tg != None: + data = {'token': token, 'id': id, 'tg': str(tg)} + else: + data = {'token': token, 'id': id, 'tg': None} + return call('api/update_tg/', data) + +def update_ds(token, id, ds): + data = {'token': token, 'id': id, 'ds': str(ds)} + return call('api/update_ds/', data) + +def update_mine(token, id, mine): + data = {'token': token, 'id': id, 'mine': str(mine)} + return call('api/update_mine/', data) + +def update_nick(token, id, nick): + data = {'token': token, 'id': id, 'nick': nick} + return call('api/update_nick/', data) + +def update_passwd(token, id, passwd): + data = {'token': token, 'id': id, 'passwd': hash(passwd)} + return call('api/update_passwd/', data) + + +def check_bal(token, id): + data = {'token': token, 'id': id} + return call('api/check_bal/', data) + +def get_nick(token, id): + data = {'token': token, 'id': id} + return call('api/get_nick/', data) + +def get_tg(token, id): + data = {'token': token, 'id': id} + return call('api/get_tg/', data) + +def get_ds(token, id): + data = {'token': token, 'id': id} + return call('api/get_ds/', data) + +def get_mine(token, id): + data = {'token': token, 'id': id} + return call('api/get_mine/', data) + +def get_passwd(token, id): + data = {'token': token, 'id': id} + return call('api/get_passwd/', data) + +#print( user_in_db('ee77b9d8-44f3-4e01-a702-69d5524ee50b', '1234') ) diff --git a/db.py b/db.py new file mode 100644 index 0000000..9eb606b --- /dev/null +++ b/db.py @@ -0,0 +1,33 @@ +import os +import json + +if not os.path.exists('db.json'): + db = {'tokens': [], + 'id': {}, + 'tg': {}, + 'ds': {}, + 'mine': {}, + 'nick': {}} + js = json.dumps(db, indent=2) + with open("db.json", "w") as outfile: + outfile.write(js) + print('Created new db.json') + +if not os.path.exists('conf.json'): + db = {'api_token': 'None', + 'tg_token': 'None', + 'ds_token': 'None'} + js = json.dumps(db, indent=2) + with open("conf.json", "w") as outfile: + outfile.write(js) + print('Created new conf.json') + +def read(file = 'db.json'): + with open(file, "r", encoding="utf-8") as openfile: + db = json.load(openfile) + return db + +def write(db, file = 'db.json'): + js = json.dumps(db, indent=2, ensure_ascii=False) + with open(file, "w", encoding="utf-8") as outfile: + outfile.write(js) diff --git a/tg.py b/tg.py new file mode 100644 index 0000000..38521a3 --- /dev/null +++ b/tg.py @@ -0,0 +1,177 @@ +import telebot +from telebot.formatting import hcode +from telebot.types import ReplyKeyboardMarkup, KeyboardButton +from datetime import datetime + +from call2api import * +from db import * + +API_TOKEN = read('conf.json')['api_token'] +TG_TOKEN = read('conf.json')['tg_token'] +bot = telebot.TeleBot(TG_TOKEN) + +LCTIME = datetime.now() + +def checkauth(message, reg = False): + if user_in_db(API_TOKEN, tg=message.chat.id) != 'false': + return True + else: + if not reg: + markup = ReplyKeyboardMarkup(resize_keyboard=True) + markup.add('Баланс') + #markup.add('Перевод') + markup.add('Помощь') + bot.reply_to(message, '''Пожалуйста, зарегистрируйтесь или войдите: +/reg Nickname 1234567890 +/login Nickname 1234567890 + +Ник вводить желательно игровой. +Пароль любой.''', reply_markup=markup) + return False + +@bot.message_handler(commands=['start']) +def start(message): + markup = ReplyKeyboardMarkup(resize_keyboard=True) + + markup.add('Баланс') + markup.add('Помощь') + + if not checkauth(message): + pass + else: + bot.reply_to(message, 'Всё работает', reply_markup=markup) + +@bot.message_handler(commands=['help']) +def help(message): + bot.reply_to(message, f'''Исходный код: https://gitea.del.pw/justuser/CryptoDM + +Доступные команды: +{hcode("""/help - Помощь +/reg ник - Регистрация +/login ник пароль - Войти в аккаунт +/unreg - Выйти из аккаунта +/passwd пароль - Смена пароля +/bal - Баланс +/pay ник сумма - Перевод +""")} +''', parse_mode='HTML') + +@bot.message_handler(commands=['reg']) +def reg(message): + if not checkauth(message, reg=True): + global LCTIME + time_delta = datetime.now() - LCTIME + if time_delta.seconds < 1: + bot.reply_to(message, 'Большая нагрузка, повторите запрос позже...') + return 0 + if len(message.text.split()) == 3: + com, nick, passwd = message.text.split() + # Проверяем нет ли такого же ника + if user_in_db(API_TOKEN, nick=nick) == 'false': + if user_add(API_TOKEN, nick, passwd, tg=message.chat.id) == 'OK': + bot.reply_to(message, 'Вы успешно зарегистрированны!') + else: + bot.reply_to(message, 'Что-то пошло не так...') + else: + bot.reply_to(message, 'Уже существует пользователь с таким ником') + else: + bot.reply_to(message, '/reg ник пароль') + else: + bot.reply_to(message, 'Вы уже зарегистрированны') + +@bot.message_handler(commands=['login']) +def login(message): + if len(message.text.split()) == 3: + global LCTIME + time_delta = datetime.now() - LCTIME + if time_delta.seconds < 1: + bot.reply_to(message, 'Большая нагрузка, повторите запрос позже...') + return 0 + com, nick, passwd = message.text.split() + id = user_in_db(API_TOKEN, nick=nick) + print('!!!!', get_tg(API_TOKEN, id)) + if get_tg(API_TOKEN, id) != 'null': + bot.reply_to(message, 'Этот пользователь уже авторизован') + elif get_passwd(API_TOKEN, id) == hash(passwd): + if update_tg(API_TOKEN, id, message.chat.id) == 'OK': + bot.reply_to(message, 'Вы успешно авторизовались!') + else: + bot.reply_to(message, 'Пароль не совпадает') + else: + bot.reply_to(message, '/login пароль') + +@bot.message_handler(commands=['unreg']) +def unreg(message): + id = user_in_db(API_TOKEN, tg=message.chat.id) + if update_tg(API_TOKEN, id, 'None') == 'OK': + bot.reply_to(message, 'Вы успешно вышли из аккаунта') + +''' +@bot.message_handler(commands=['unreg']) +def unreg(message): + id = user_in_db(API_TOKEN, tg=message.chat.id) + print(int(id)) + print("1") + if user_del(API_TOKEN, id) == 'OK': + bot.reply_to(message, 'OK') +''' + +@bot.message_handler(commands=['passwd']) +def passwd(message): + if checkauth(message): + if len(message.text.split()) == 2: + com, passwd = message.text.split() + id = user_in_db(API_TOKEN, tg=message.chat.id) + if update_passwd(API_TOKEN, id, passwd) == 'OK': + bot.reply_to(message, 'Пароль успешно изменён.') + else: + bot.reply_to(message, 'Что-то пошло не так...') + else: + bot.reply_to(message, '/passwd новый_пароль') + + +@bot.message_handler(commands=['bal']) +def bal(message): + if checkauth(message): + id = user_in_db(API_TOKEN, tg=message.chat.id) + coins = check_bal(API_TOKEN, id) + nick = get_nick(API_TOKEN, id) + bot.reply_to(message, f'''Ваш баланс: {hcode(coins)} CDM + +Ник: {hcode(nick)}''', parse_mode='HTML') + +@bot.message_handler(commands=['pay']) +def pay(message): + if checkauth(message): + if len(message.text.split()) == 3: + com, nick, amount = message.text.split() + if float(amount) <= 0.0001: + bot.reply_to(message, 'Слишком малое или недопустимое значение.') + return 0 + amount = str(float(amount)) # Защиты от 1000 нулей в начале + src_id = user_in_db(API_TOKEN, tg=message.chat.id) + dst_id = user_in_db(API_TOKEN, nick=nick) + if dst_id == 'false': + bot.reply_to(message, 'Не существует такого пользователя.') + else: + status = coins_transfer(API_TOKEN, src_id, dst_id, amount) + if status == 'No_money': + bot.reply_to(message, 'Недостаточно средств.') + elif status == 'OK': + bot.reply_to(message, f'''Успешно переведено {hcode(amount)} CDM. +Адресат: {hcode(nick)}''', parse_mode='HTML') + bot.send_message(int(get_tg(API_TOKEN, dst_id)), f'''Вам перевели {hcode(amount)} CDM. + +Отправитель: {hcode(get_nick(API_TOKEN, src_id))}''', parse_mode='HTML') + else: + bot.reply_to(message, '/pay ник количество') + +@bot.message_handler(func=lambda message: True) +def checks(message): + if message.text == 'Баланс': + bal(message) + elif message.text == 'Помощь': + help(message) + + +bot.infinity_polling() diff --git a/token_gen.py b/token_gen.py new file mode 100644 index 0000000..ecd1296 --- /dev/null +++ b/token_gen.py @@ -0,0 +1,11 @@ +from db import * +from uuid import uuid4 + +db = read() +token = str(uuid4()) + +db['tokens'].append(token) +write(db) + +print(f'Сгенерирован новый токен: {token}') +