You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

246 lines
7.3 KiB

import traceback
import steam as SteamPy
import argparse, os, sys
import asyncio
from colors import *
from json import load
import asyncio
from steam.errors import Forbidden as STEAM_FORBIDDEN
from backend_integration import BackendClient
class TradeChecker:
APP_ID = 440
MONTH = 2678400
WEEK = 604800
DAY = 86400
prices_map = {}
def __init__(self, prices):
for price in prices:
if price["money_price"] == 0:
continue
self.prices_map[price['period']] = int(price["item_price"].split()[0])
if not self.prices_map:
error("cannot parse prices")
sys.exit(228)
#else:
# info(f"{self.prices_map}")
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)
#ключ всегда месяц ибо стабильная единица
if(key_count >= self.prices_map["month"]):
final_amount += key_count * self.MONTH
if(metal_count >= self.prices_map["week"]):
final_amount += (metal_count / self.prices_map["week"]) * self.WEEK
elif(metal_count >= self.prices_map["day"]):
final_amount += (metal_count / self.prices_map["day"]) * 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 = None
trade_tracker = {}
backend : BackendClient = None
backend_checker_enable = False
async def on_ready(self):
info(f"Logged in as: {self.user}")
asyncio.ensure_future(self.backend_checker(60))
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 update_prices(self, exit_if_error = False):
prices = await self.backend.prices(exit_if_error)
self.items = TradeChecker(prices)
async def backend_checker(self, timeout=60):
if not self.backend_checker_enable:
info(f"Check backend stats every {timeout} seconds")
self.backend_checker_enable = True
while True:
await self.backend.pulse(True)
await self.update_prices(True)
await asyncio.sleep(timeout)
#Проверка шмота на леквид
async def on_trade(self, trade: SteamPy.TradeOffer):
if not self.items:
info("prices is not setup")
await self.update_prices()
info(f"[{trade.id}] Incoming trade from [{trade.partner.id}] {trade.partner.name}")
if trade.is_our_offer():
warning(f"[{trade.id}] trade from me, ignoring")
return
if trade.state != SteamPy.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) > 50:
warning(f"[{trade.id}] cannot accept trade with more 50 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")
try:
await trade.accept()
except STEAM_FORBIDDEN as err:
traceback.print_exc()
error("Restart app, steam return forbidden on accept trade")
sys.exit(1)
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_update(self, _, trade: SteamPy.TradeOffer):
if trade.state != SteamPy.enums.TradeOfferState.Accepted:
warning(f"[{trade.id}] Trade dont have status Accepted, ignore")
return
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, unique=f"steam_{trade.id}")
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')}")
backend = BackendClient()
asyncio.get_event_loop().run_until_complete(backend.pulse(True))
if not backend.up:
print("backend not working down bot")
sys.exit(200)
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()
client.backend = backend
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"],
debug = True
)