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 )