Browse Source

rewrited on v1 bot

master
gsd 2 years ago
commit
84055d431a
  1. 2
      .dockerignore
  2. 2
      .gitignore
  3. 23
      Dockerfile
  4. 29
      colors.py
  5. 72
      db_driver.py
  6. 43
      discord_alarm.py
  7. BIN
      docker-compose.yaml
  8. 176
      tradebot.facti13.py

2
.dockerignore

@ -0,0 +1,2 @@
auth_data/
.env

2
.gitignore

@ -0,0 +1,2 @@
auth_data/
.env

23
Dockerfile

@ -0,0 +1,23 @@
FROM python:3.7
RUN groupadd -g 1000 service && useradd -g 1000 -u 1000 service
ENV TZ=Europe/Moscow
RUN python -m pip install aiomysql aiohttp steamio
RUN mkdir /home/service && \
cp /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata
ENV PYTHONUNBUFFERED 1
WORKDIR /home/service
COPY ./ ./
RUN chown service:service -R /home/service && chmod 775 -R /home/service
USER service
ENTRYPOINT ["python", "tradebot.facti13.py"]

29
colors.py

@ -0,0 +1,29 @@
from time import strftime
class colors:
HEADER = u'\033[95m'
OKBLUE = u'\033[94m'
OKGREEN = u'\033[92m'
WARNING = u'\033[93m'
FAIL = u'\033[91m'
ENDC = u'\033[0m'
BOLD = u'\033[1m'
UNDERLINE = u'\033[4m'
HEADER = u"[{:^7}] ({:^17}) {}"
def ok(text):
HEAD = colors.OKGREEN + u"OK" + colors.ENDC
return print(HEADER.format(HEAD, strftime(u"%H:%M:%S %d.%m.%y"), text))
def error(text):
HEAD = colors.FAIL + u"FAIL" + colors.ENDC
return print(HEADER.format(HEAD, strftime(u"%H:%M:%S %d.%m.%y"), text))
def warning(text):
HEAD = colors.WARNING + u"WARNING" + colors.ENDC
return print(HEADER.format(HEAD, strftime(u"%H:%M:%S %d.%m.%y"), text))
def info(text):
HEAD = colors.HEADER + u"INFO" + colors.ENDC
return print(HEADER.format(HEAD, strftime(u"%H:%M:%S %d.%m.%y"), text))

72
db_driver.py

@ -0,0 +1,72 @@
import asyncio
from cmath import inf
import aiomysql
from steam import SteamID
from colors import *
class Database:
database = None
permitions = {"VIP":("20:oa",2592000)}
def __init__(self, host, user, password, db):
self.host = host
self.user = user
self.password = password
self.db = db
async def connect(self):
info("Create database pool")
self.database = await aiomysql.create_pool(
host = self.host,
user = self.user,
password = self.password,
db=self.db
)
async def disconnect(self):
ok("Disconnect from database")
await self.database.wait_closed()
async def processing_vip(self, steamid: SteamID, amount, status = "VIP", who = "Donate.User"):
check_status = await self.check_update_VIP(steamid)
if check_status:
if check_status > 1:
info(f"Append more time to {steamid.community_url}")
return await self.update_user(steamid, amount)
else:
info(f"Create new vip user {steamid.community_url}")
return await self.add_new_user(steamid, amount, status, who)
else:
warning(f"{steamid.community_url} currently have ADMIN/MOD permitions")
return False
async def check_update_VIP(self, steamid: SteamID):
# 0 = mod/admin | -1 = not found | 1 = need update
query = f"SELECT * FROM `sm_admins` WHERE `identity` LIKE '{steamid.id2_zero}' ORDER BY `reg_date` DESC"
async with self.database.acquire() as connection:
async with connection.cursor(aiomysql.DictCursor) as cursor:
await cursor.execute(query)
for row in await cursor.fetchall():
if row["status"] == "VIP" and row["amount"] > 0:
return 1
else:
return 0
return -1
async def update_user(self, steamid: SteamID, amount):
query = f"UPDATE `sm_admins` SET `amount`=`amount`+{amount}, `reg_date`=`reg_date` WHERE `identity` LIKE '{steamid.id2_zero}'"
async with self.database.acquire() as connection:
async with connection.cursor(aiomysql.DictCursor) as cursor:
await cursor.execute(query)
await cursor.commit()
return 101
async def add_new_user(self, steamid: SteamID, amount, status, who):
settings = self.permitions.get(status)
level, flags = settings[0].split(":")
query = f"INSERT INTO `sm_admins` (`id`, `authtype`, `identity`, `password`, `flags`, `name`, `immunity`, `comment`, `status`, `reg_date`, `amount`) VALUES (NULL, 'steam', '{steamid.id2_zero}', NULL, '{flags}', '', '{level}', '{who}', '{status}', CURRENT_TIMESTAMP,'{amount}')"
async with self.database.acquire() as connection:
async with connection.cursor(aiomysql.DictCursor) as cursor:
await cursor.execute(query)
await cursor.commit()
return 100

43
discord_alarm.py

@ -0,0 +1,43 @@
import aiohttp
from random import choice
from steam import SteamID
class DiscordAlarm:
def __init__(self, webhook_url):
self.url = webhook_url
async def alert(self, steamid: SteamID, amount):
try:
await self.send(self.prepare_payload(steamid, amount))
except:
pass
def prepare_payload(self, steamid: SteamID, amount):
phrare = [
"Поздравим очередного игрока с покупкой випа!",
"Очередной игрок приобрел вип.",
"Ура кто-то украл деньги у мамки и принес их нам!!!",
"Делать деньги, делать деньги блять вот так..."
]
payload = {"embeds":[{"fields":[]}]}
payload.update({"content":choice(phrare)})
payload["embeds"][0]["fields"].append({
"name": "Ссылка на игрока:",
"value": steamid.community_url,
"inline": True
})
payload["embeds"][0]["fields"].append({
"name": "Количество дней:",
"value": "{}".format(round(amount / 60 / 60 / 24)),
"inline": True
})
payload["embeds"][0]["fields"].append({
"name": "Оплата:",
"value": "{}".format("Steam"),
"inline": True
})
return payload
async def send(self, payload):
async with aiohttp.ClientSession() as session:
await session.post(self.url, json = payload)

BIN
docker-compose.yaml

Binary file not shown.

176
tradebot.facti13.py

@ -0,0 +1,176 @@
from cmath import inf
from pydoc import cli
import steam as SteamPy
import argparse, os, sys
from colors import *
from db_driver import Database
from json import load
from discord_alarm import DiscordAlarm
class TradeChecker:
APP_ID = 440
MONTH = 2678400
WEEK = 604800
DAY = 86400
def mannco_key(self, items):
class_id = 101785959
instance_id = 11040578
count = 0
for item in items:
#print(f"{item._app_id} {item.class_id} {item.instance_id}")
if int(item._app_id) == self.APP_ID and int(item.class_id) == class_id and int(item.instance_id) == instance_id:
count += 1
return count
def pure_metal(self, items):
class_id = 2674
instance_id = 11040547
count = 0
for item in items:
#print(f"{item._app_id} {item.class_id} {item.instance_id}")
if int(item._app_id) == self.APP_ID and int(item.class_id) == class_id and int(item.instance_id) == instance_id:
count += 1
return count
def Items2Seconds(self, items):
key_count = self.mannco_key(items)
metal_count = self.pure_metal(items)
final_amount = 0
#print(key_count, ",", metal_count)
final_amount += key_count * self.MONTH
if(metal_count >= 20):
final_amount += (metal_count / 20) * self.WEEK
elif(metal_count >= 5):
final_amount += (metal_count / 5) * self.DAY
return final_amount
async def send_msg(trade: SteamPy.TradeOffer, message: str):
try:
await trade.partner.send(message)
except:
error(f"[{trade.id}] Cannot send message")
class SteamClient(SteamPy.Client):
db = None
items = TradeChecker()
discord_alarm = None
async def on_ready(self):
info(f"Logged in as: {self.user}")
async def on_connect(self):
ok("Success connect to steam")
await self.db.connect()
async def on_disconnect(self):
ok("Disconnect from steam")
await self.db.disconnect()
#Проверка шмота на леквид
async def on_trade_receive(self, trade: SteamPy.TradeOffer):
info(f"[{trade.id}] Incoming trade from [{trade.partner.id}] {trade.partner.name}")
if trade.state != SteamPy.enums.TradeOfferState.Active:
error(f"[{trade.id}] trade have not active stats")
await send_msg(trade, "Бот не сможет принять трейд от тебя по причине удержания вещей с твоей стороны")
await trade.decline()
return
if not trade.is_gift():
warning(f"[{trade.id}] partner wanna get bot items, decine trade")
await send_msg(trade, "Не пытайся спиздить вещи у бота")
await trade.decline()
return
if len(trade.items_to_receive) > 25:
warning(f"[{trade.id}] cannot accept trade with more 25 items")
await send_msg(trade, "За один раз можно отправить неболее 25 вещей")
await trade.decline()
return
seconds = self.items.Items2Seconds(trade.items_to_receive)
if seconds == 0:
error(f"[{trade.id}] cannot accept trade not valid items")
await send_msg(trade, "Ты отправил неправльные вещи! Проверь что это:\n- Ключ МаннКо (уникальный)\n- Очищенный метал (уникальный)")
await trade.decline()
return
info(f"[{trade.id}] Try accept trade")
await send_msg(trade, "Попытка принять трейд...")
await trade.accept()
return
#Принятый трейд
async def on_trade_accept(self, trade: SteamPy.TradeOffer):
if not trade.is_gift():
return
info(f"[{trade.id}] Final stage accepted trade [{trade.partner.id}] {trade.partner.name}")
await send_msg(trade, "Успешно, сейчас посчитаем сколько ты надонатил")
seconds = self.items.Items2Seconds(trade.items_to_receive)
result = await self.db.processing_vip(trade.partner, seconds)
if result == False:
await send_msg(trade, "Спасибо за вещи, но у тебя уже есть КРУТЫЕ права на фактах")
elif result == 100:
await send_msg(trade, f"Мои поздавления! Ты получил випку на {seconds / 60 / 60 / 24} дней")
elif result == 101:
await send_msg(trade, f"Круто! Ты продлил випку на {seconds / 60 / 60 / 24} дней")
await self.discord_alarm.alert(trade.partner, seconds)
return
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--auth-file", type=str, default=os.environ.get("AUTH_FILE", ""))
parser.add_argument("--steam-secret", type=str, default=os.environ.get("STEAM_SECRET", ""))
parser.add_argument("--db-host", type=str, default=os.environ.get("DB_HOST", ""))
parser.add_argument("--db-username", type=str, default=os.environ.get("DB_USERNAME", ""))
parser.add_argument("--db-password", type=str, default=os.environ.get("DB_PASSWORD", ""))
parser.add_argument("--db-name", type=str, default=os.environ.get("DB_NAME", ""))
parser.add_argument("--discord-url", type=str, default=os.environ.get("DISCORD_WEBHOOK_URL", ""))
args = parser.parse_args()
client = SteamClient(game = SteamPy.Game(id=440))
if args.db_host and args.db_username and args.db_password and args.db_name:
client.db = Database(args.db_host, args.db_username, args.db_password, args.db_name)
else:
error("DB data not be setted")
sys.exit(1)
if args.auth_file and args.steam_secret:
try:
with open(args.auth_file, "r") as auth_file:
login = auth_file.readline()[:-1]
password = auth_file.readline()
except:
error("steam auth data is not correct")
sys.exit(3)
try:
with open(args.steam_secret, "r") as steam_file:
secrets = load(steam_file)
#shared_secret
#identity_secret
except:
error("steam secret is not correct")
sys.exit(4)
else:
error("steam auth data or steam secret not be setted")
sys.exit(2)
if args.discord_url:
client.discord_alarm = DiscordAlarm(args.discord_url)
else:
error("need discord webhook")
sys.exit(5)
client.run(
username=login,
password = password,
shared_secret=secrets["shared_secret"],
identity_secret=secrets["identity_secret"],
)
Loading…
Cancel
Save