Browse Source

backend integration

master
gsd 2 years ago
parent
commit
ee9b70aaef
  1. 2
      Dockerfile
  2. 52
      backend_integration.py
  3. BIN
      docker-compose.yaml
  4. 13
      git_build/Dockerfile
  5. 185
      tradebot.facti13.external.py
  6. 421
      tradebot.facti13.internal.py

2
Dockerfile

@ -20,4 +20,4 @@ RUN chown service:service -R /home/service && chmod 775 -R /home/service
USER service USER service
ENTRYPOINT ["python", "tradebot.facti13.py"] ENTRYPOINT ["python"]

52
backend_integration.py

@ -0,0 +1,52 @@
import aiohttp, os, sys
from colors import *
import traceback
from steam import SteamID
class BackendClient:
up = False
def __init__(self):
if not os.getenv("BACKEND_URL", ""):
error("BACKEND_URL not setted in env")
sys.exit(10)
if not os.getenv("SECRET_KEY", ""):
error("SECRET_KEY not setted in env")
sys.exit(11)
self.secret_key = os.getenv("SECRET_KEY")
self.pulse_url = f"{os.getenv('BACKEND_URL')}/api/pulse"
self.vip_url = f"{os.getenv('BACKEND_URL')}/api/external/vip"
async def pulse(self):
async with aiohttp.ClientSession(cookies={
"secretkey":self.secret_key}) as session:
async with session.get(self.pulse, ssl=False) as response:
try:
await response.text()
self.up = True
except:
error("Backend not respond")
traceback.print_exc()
self.up = False
return self.up
async def vip(self, steamid: SteamID, amount: int, extra: str):
async with aiohttp.ClientSession(cookies={
"secretkey":self.secret_key}) as session:
async with session.post(self.vip_url + f"?steam={steamid.id64}&amount={amount}&service=steam&extra={extra}", ssl=False) as response:
try:
result = int(await response.text())
if result == 0:
warning(f"[S64:{steamid.id64}] VIP as not be added, maybe permition already exists")
return 99
elif result > 0:
info(f"[S64:{steamid.id64}] VIP has be added!")
return 100
elif result < 0:
info(f"[S64:{steamid.id64}] VIP has be extends!")
return 101
except:
error(f"[S64:{steamid.id64}] Backend returned error")
traceback.print_exc()
return False
return False

BIN
docker-compose.yaml

Binary file not shown.

13
git_build/Dockerfile

@ -0,0 +1,13 @@
FROM python:3.10
RUN python -m pip install aiomysql aiohttp steamio git+https://github.com/conqp/rcon
WORKDIR /app
ENV TZ=Europe/Moscow
ENV PYTHONUNBUFFERED 1
RUN mkdir /home/service && \
cp /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata
ENV BUILDDATE ${BUILDDATE}
RUN cd /tmp && git clone https://git.pblr-nyk.pro/gsd/Facti13.SteamTradeBot.v2 && cp -a Facti13.SteamTradeBot.v2/. /app && rm -r Facti13.SteamTradeBot.v2
ENTRYPOINT ["python"]

185
tradebot.facti13.external.py

@ -0,0 +1,185 @@
import steam as SteamPy
import argparse, os, sys
from colors import *
from json import load
import asyncio
from backend_integration import BackendClient
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):
items = TradeChecker()
trade_tracker = {}
backend = BackendClient()
async def on_ready(self):
info(f"Logged in as: {self.user}")
async def on_connect(self):
await self.backend.pulse()
ok("Success connect to steam")
async def on_disconnect(self):
await self.backend.pulse()
ok("Disconnect from steam")
#Проверка шмота на леквид
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 trade.decline()
return
if not trade.is_gift():
warning(f"[{trade.id}] partner wanna get bot items, decine trade")
await trade.decline()
return
if len(trade.items_to_receive) > 25:
warning(f"[{trade.id}] cannot accept trade with more 25 items")
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 trade.decline()
return
pulse_result = await self.backend.pulse()
if not pulse_result:
error("Backend not response ot pulse, drop trade")
return
info(f"[{trade.id}] Try accept trade")
await trade.accept()
info(f"[{trade.id}] Maybe trade acceped...")
#Force on trade accept
await asyncio.sleep(3)
if not trade.id in self.trade_tracker:
self.trade_tracker[trade.id] = 60
while self.trade_tracker[trade.id] > 2:
await asyncio.sleep(1)
self.trade_tracker[trade.id] -= 1
await self.on_trade_accept(trade)
return
#Принятый трейд
async def on_trade_accept(self, trade: SteamPy.TradeOffer):
info(f"[{trade.id}] Finalize accept")
if trade.id in self.trade_tracker and self.trade_tracker[trade.id] == 0:
return
if trade.id in self.trade_tracker and self.trade_tracker[trade.id] > 0:
self.trade_tracker[trade.id] = 0
if not trade.id in self.trade_tracker:
self.trade_tracker[trade.id] = 0
if not trade.is_gift():
return
info(f"[{trade.id}] Final stage accepted trade [{trade.partner.id}] {trade.partner.name}")
pulse_result = await self.backend.pulse()
if not pulse_result:
warning("Backend not responde, any time try add vip")
extra = f"keys={self.items.mannco_key(trade.items_to_receive)};metal={self.items.pure_metal(trade.items_to_receive)};"
seconds = self.items.Items2Seconds(trade.items_to_receive)
result = await self.backend.vip(trade.partner, seconds, extra)
if result == 99:
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} дней")
else:
await send_msg(trade, "Произошла ошибка добавление випа, сообщи об этом разрабу")
return
if __name__ == "__main__":
print(f"Build date: {os.getenv('BUILDDATE', 'not set')}")
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", ""))
args = parser.parse_args()
client = SteamClient(game = SteamPy.Game(id=440))
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)
client.run(
username=login,
password = password,
shared_secret=secrets["shared_secret"],
identity_secret=secrets["identity_secret"],
)

421
tradebot.facti13.py → tradebot.facti13.internal.py

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