__version__ = (1, 0, 0) # # @@@@@@ @@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@ # @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@ # @@! @@@ !@@ @@! @@! @@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@! !@@ # !@! @!@ !@! !@! !@! @!@ !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! !@! !@! # @!@!@!@! !!@@!! @!! @!@!!@! @!@ !@! @!! !!@ @!@ @!@ !@! @!@ !@! @!@ !@! @!! @!!!:! !!@@!! # !!!@!!!! !!@!!! !!! !!@!@! !@! !!! !@! ! !@! !@! !!! !@! !!! !@! !!! !!! !!!!!: !!@!!! # !!: !!! !:! !!: !!: :!! !!: !!! !!: !!: !!: !!! !!: !!! !!: !!! !!: !!: !:! # :!: !:! !:! :!: :!: !:! :!: !:! :!: :!: :!: !:! :!: !:! :!: !:! :!: :!: !:! # :: ::: :::: :: :: :: ::: ::::: :: ::: :: ::::: :: :::: :: ::::: :: :: :::: :: :::: :::: :: # : : : :: : : : : : : : : : : : : : : :: : : : : : : :: : : : :: :: :: : : # # © Copyright 2024 # # https://t.me/Den4ikSuperOstryyPer4ik # and # https://t.me/ToXicUse # # 🔒 Licensed under the GNU AGPLv3 # https://www.gnu.org/licenses/agpl-3.0.html # # meta banner: # meta developer: @AstroModules # required: steampy # meta banner: https://raw.githubusercontent.com/Den4ikSuperOstryyPer4ik/Astro-modules/main/Banners/AstroSteamNow.png # Part of the module taken from WakaTime by @hikariatama: 38, 158, 208, 324 lines import time import logging import datetime import requests import asyncio from steampy.client import SteamClient from .. import loader, utils from ..inline.types import InlineCall from telethon.errors.rpcerrorlist import MessageNotModifiedError logger = logging.getLogger(__name__) @loader.tds class Steam(loader.Module): '''Get now played game''' strings = { 'name': 'SteamNow', '_api_key': "Enter your SteamAPI Key. You can get it by following this tutorial:\n\nhttps://t.me/help_code/20", # Tutorial link '_account_id': "Enter your Steam Account ID. More details in the tutorial: \n\nhttps://t.me/help_code/21", # Tutorial link 'no_api_key_or_id': ( '❌ You did not specify your API_KEY or ACCOUNT_ID in the config.\n' '🚨 Correct this for further module operation' ), 'noGame': "❌ The game is not running or you do not have access", 'steamNow': ( '💻 At the moment you are playing:\n\n' '🎮 Title: {}\n' '🆔 Game ID: {}' ), 'lite_gameInfo': ( '🎮 Game information:\n\n' 'Title: {}\n' 'Price: {}\n' 'Description:\n- {}' ), 'steamMe': ( '🎮 Your account:\n\n' 'Name: {} ({})\n' 'Online: {}\n' 'Created: {}\n' 'Recent games:\n • {}' ), 'gameNotFound': '🆔 There is no game with such an identifier, try again', "state": "🙂 Steam widgets: {}\n{}", "error": "Steam error\n\n{}", "tutorial": ( "ℹ️ To enable the widget, send this text to any chat:" " {STEAMNOW}" ), "configuring": "🙂 Steam widget will be ready soon...", } strings_ru = { '_api_key': "Введите ваш SteamAPI Key. Получить его можно по туториалу:\n\n", # Линк на тутор '_account_id': "Введите ваш Steam Account ID. Подробнее в туториале: \n\n", # Линк на тутор 'no_api_key_or_id': ( '❌ Вы не указали ваш API_KEY или ACCOUNT_ID в конфиге.\n' '🚨 Исправьте это для дальнейшей работы модуля' ), 'noGame': "❌ Игра не запущена, или у вас нет доступа", 'steamNow': ( '💻 В данный момент вы играете:\n\n' '🎮 Название: {}\n' '🆔 ID Игры: {}' ), 'lite_gameInfo': ( '🎮 Информация об игре:\n\n' 'Название: {}\n' 'Цена: {}\n' 'Описание:\n- {}' ), 'steamMe': ( '🎮 Ваш аккаунт:\n\n' 'Имя: {} ({})\n' 'В сети: {}\n' 'Создан: {}\n' 'Последние игры:\n • {}' ), 'gameNotFound': '🆔 Игры с таким идентификатором нет, попробуйте снова', "state": "🙂 Steam виджеты: {}\n{}", "error": "Steam error\n\n{}", "tutorial": ( "ℹ️ Для включения виджета отправьте данный текст в любой чат:" " {STEAMNOW}" ), "configuring": "🙂 Steam виджет скоро будет готов...", } def __init__(self): self.config = loader.ModuleConfig( loader.ConfigValue( 'API_KEY', None, doc=lambda: self.strings('_api_key'), validator=loader.validators.Hidden(), ), loader.ConfigValue( 'ACCOUNT_ID', None, doc=lambda: self.strings('_account_id') ), loader.ConfigValue( "update_interval", 300, lambda: "Messages update interval. Not recommended < 300 seconds", validator=loader.validators.Integer(minimum=60), ), ) async def client_ready(self, client, db): self.db.set( "Steam", "widgets", list(map(tuple, self.db.get("Steam","widgets", []))) ) self._task = asyncio.ensure_future(self._parse()) async def steam_requests(self, request, gameId: bool = None): '''Function for requests to SteamAPI''' api_key = self.config['API_KEY'] account_id = self.config['ACCOUNT_ID'] steam_client = SteamClient(api_key) if request == 'SteamNow': if not api_key or not account_id: return('TokenError', None) data = {'key': api_key, 'steamids': account_id} response = steam_client.api_call('GET', 'ISteamUser', 'GetPlayerSummaries', 'v2', data).json()['response'] try: gameId = response['players'][0]['gameid'] gameName = response['players'][0]['gameextrainfo'] text = self.strings('steamNow').format(gameName, gameId) except: text, gameId = self.strings('noGame'), None return text, gameId #, photo elif request == 'profileInfo': if not api_key or not account_id: return('TokenError', None, None, None, None, None) url = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={}&steamids={}' url2 = 'http://api.steampowered.com/IPlayerService/GetRecentlyPlayedGames/v0001/?key={}&steamid={}&format=json' response = requests.get(url.format(self.config['API_KEY'], self.config['ACCOUNT_ID'])).json()['response']['players'][0] recentGameInfo = requests.get(url2.format(self.config['API_KEY'], self.config['ACCOUNT_ID'])).json()['response']['games'] games = [] for game in recentGameInfo: games.append(f'{game["name"]}: {game["playtime_2weeks"]}м. ({game["playtime_forever"]}м.)') recentGames = '\n • '.join(games) return( response['avatarfull'], # Profile photo response['personaname'], # Name: 'ˢˡ ToxUniҨue, response['realname'], # Realname: Tox. datetime.datetime.fromtimestamp(response['lastlogoff']).isoformat().replace('T', ' '), # Последний раз в сети datetime.datetime.fromtimestamp(response['timecreated']).isoformat().replace('T', ' '), # Дата создания аккаунта recentGames ) elif request == 'GameInfo': if not api_key or not account_id: return('TokenError', None) url = f"http://store.steampowered.com/api/appdetails?appids={gameId}" response = requests.get(url) data = response.json() game_data = data[str(gameId)]['data'] capsule_image = game_data.get('header_image', None) name = game_data.get('name', None) short_description = game_data.get('short_description', None) price_overview = game_data.get('price_overview', None) if price_overview: initial_formatted_price = price_overview.get('initial_formatted', None) final_formatted_price = price_overview.get('final_formatted', None) else: initial_formatted_price = None final_formatted_price = None final_price = f'{initial_formatted_price}' if initial_formatted_price == final_formatted_price else f'{final_formatted_price} ({initial_formatted_price})' text = self.strings('lite_gameInfo').format(name, final_price, short_description) return capsule_image, text async def game_info_i( self, call: InlineCall, gameId: int, message ): _, text = await self.steam_requests('GameInfo', gameId) if _ == 'TokenError': return await call.edit(text=self.strings('no_api_key_or_id')) await call.edit(text=text) async def _parse(self, do_not_loop: bool = False): while True: if self.config["API_KEY"] == None or self.db.get("Steam", "state") == False: await asyncio.sleep(5) continue for widget in self.db.get("Steam", "widgets", []): now, _ = await self.steam_requests('SteamNow') if now == 'TokenError': await self._client.edit_message(*widget[:2], self.strings('no_api_key_or_id')) elif now == self.strings('noGame'): self.db.set('steam', 'inGame', None) await self._client.edit_message(*widget[:2], self.strings('noGame')) else: in_game_time = self.db.get('steam', 'inGame') if in_game_time is None: self.db.set('steam', 'inGame', time.time()) game_time_minutes = 0 else: game_time = time.time() - in_game_time game_time_minutes = round(game_time / 60) try: await self._client.edit_message(*widget[:2], now + f'\n\n🕓 В игре: {game_time_minutes} минут.') except: return await asyncio.sleep(int(self.config["update_interval"])) @loader.command( ru_doc=' - получить, во что я сейчас играю' ) async def steamnow(self, message): """- get what I'm playing at""" text, gameid = await self.steam_requests('SteamNow') if text == self.strings('noGame'): return await utils.answer(message, text) elif text == 'TokenError': return await utils.answer(message, self.strings('no_api_key_or_id')) capsule_image, _ = await self.steam_requests('GameInfo', gameid) await self.inline.form( message=message, photo=capsule_image, text=text, reply_markup=[ { 'text': 'Информация об игре', 'callback': self.game_info_i, 'args': (gameid, message,), } ] ) @loader.command( ru_doc='- открыть аккаунт Steam' ) async def sme(self, message): '''- my steam account''' photo, fullName, name, date1, date2, games = await self.steam_requests('profileInfo') if photo == 'TokenError': await utils.answer(message, self.strings('no_api_key_or_id')) await utils.answer_file( message, photo, caption=self.strings('steamMe').format( fullName, name, date1, date2, games ) ) @loader.command( ru_doc=' - получить инфо об игре' ) async def game(self, message): ''' - get game info''' args = utils.get_args_raw(message) try: capsule_image, text = await self.steam_requests('GameInfo', args) if capsule_image == 'TokenError': await utils.answer(message, self.strings('no_api_key_or_id')) await utils.answer_file(message, capsule_image, text) except: await utils.answer(message, self.strings('gameNotFound')) @loader.command( ru_doc='- вкл/выкл виджеты SteamNow' ) async def steamtoggle(self, message): """ - toggle widgets updates""" state = self.db.get('Steam', 'state') state = True if state == False else False self.db.set('Steam', 'state', state) await utils.answer( message, self.strings("state").format( "on" if state else "off", self.strings("tutorial") if state else "" ), ) @loader.watcher() async def watcher(self, message): if ( self.db.get('Steam', 'state') and (await self.client.get_messages(self.db.get('Steam', 'widgets')[0][0], ids=self.db.get('Steam', 'widgets')[0][1])).message == '❌ Вы не во что не играете' ): now, _ = await self.steam_requests('SteamNow') if now == self.strings('noGame') or now == 'TokenError': return await self._parse(do_not_loop=True) try: if "{STEAMNOW}" not in getattr(message, "text", "") or not message.out: return chat_id = utils.get_chat_id(message) message_id = message.id self.db.set( "Steam", "widgets", self.db.get('steam', "widgets", []) + [(chat_id, message_id, message.text)], ) await utils.answer(message, self.strings("configuring")) await self._parse(do_not_loop=True) except Exception as e: logger.exception("Can't send widget") await utils.answer(message, self.strings("error").format(e))