from email import message import json import ssl import aiohttp, os from datetime import datetime from discord import Embed from exceptions import * import yarl class Player: original_request = "" requester_steam64 = "" current = {} steamid = {} play_on = {} def __init__(self, profile, requester_steam64, stats): self.requester_steam64 = requester_steam64 self.original_request = profile self.stats = stats #потом надо будет сделать что профиль принимает все, а не только стим ид #api/profile/steam, ток там буква Z поэтому стоит поменять на секрет кей pass async def GetSteamID(self): self.steamid = await self.GetSteamIDOfProfile(self.original_request) print(self.steam64) async def LoadProfile(self): self.current = await self.GetProfile(self.steam64) @property def steam64(self): return self.steamid.get('steam64', 0) @property def community_url(self): return self.steamid.get('community_url', '') @property def permition(self): return self.current.get("permition", {}) @property def played_on_servers(self): return self.current.get("lastplay", {}) or self.current.get("gametime", {}) @property def embed(self) -> Embed: if not self.current: raise NotLoadProfile # build header prepare_description = "" if self.current.get("play_on", {}): prepare_description = f"Сейчас играет на {self.stats['servers'][self.current['play_on']['server_id']]['name']}\n" elif self.current.get("lastplay", {}): selected_srv = "srv1" selected_timestamp = 0 for srv, maps in self.current["lastplay"].items(): for last_play in maps.values(): if last_play > selected_timestamp: selected_srv = srv selected_timestamp = last_play prepare_description = f"Последняя игра на {self.stats['servers'][selected_srv]['name']}\nв {utime2human(selected_timestamp)}" else: prepare_description = "Не играл на фактах13" embed = Embed( title=self.current["steam_data"]["nickname"], description=prepare_description, url=self.current["steamids"]["community_url"]) # set image embed.set_thumbnail(url = self.current["steam_data"]["avatar"]) #Последняя игра и игровое время self.lastplayAndGametime = {} if "lastplay" in self.current and self.current["lastplay"]: for maps in self.current["lastplay"].values(): for map_name, last_play in maps.items(): if not workshopmap2bsp(map_name) in self.lastplayAndGametime: self.lastplayAndGametime[workshopmap2bsp(map_name)] = {"total":0, "lastplay":0} self.lastplayAndGametime[workshopmap2bsp(map_name)]['lastplay'] = last_play if "gametime" in self.current and self.current["gametime"]: for maps in self.current["gametime"].values(): for map_name, play_time in maps.items(): if not workshopmap2bsp(map_name) in self.lastplayAndGametime: self.lastplayAndGametime[workshopmap2bsp(map_name)] = {"total":0, "lastplay":0} self.lastplayAndGametime[workshopmap2bsp(map_name)]["total"] = play_time if len(list(self.lastplayAndGametime.keys())) > 0: message = "" for map_name, values in self.lastplayAndGametime.items(): message += f"{map_name}\n{human_TIME(values['total']) if values['total'] > 0 else 'Не играл'} / {utime2human(values['lastplay']) if values['lastplay'] > 0 else 'Не играл'}\n" embed.add_field(name="Статистика игры", value=message, inline=False) # Права if self.current.get("permition", {}): message = f"{self.current['permition']['status']} назначен {utime2human(self.current['permition']['u_timestamp']) if self.current['permition']['u_timestamp'] != 0 else 'с момента создания'}\n" if self.current['permition'].get('amount', 0) and self.current['permition'].get("u_timestamp", 0): message += f"окончание после {utime2human(self.current['permition']['u_timestamp'] + self.current['permition']['amount'])}\n" embed.add_field(name="Права на серверах", value=message, inline=False) # Бан if self.current.get("ban", {}): message = f"Ник: {self.current['ban']['player_name']}\n" message += f"Причина: {self.current['ban']['ban_reason']}\n" message += f"Время: {utime2human(self.current['ban']['ban_utime'])}\n" message += f"Кто забанил: {self.current['ban']['banned_by']} | <@{self.current['ban']['admin_info']['discord_id']}>\n" if self.current['ban']['active'] == True: if self.current['ban']['ban_length'] == 0: message += "Данный бан навсегда!\n" else: message += f"Дата разбана: {utime2human(self.current['ban']['ban_utime'] + self.current['ban']['ban_length_seconds'])}\n" embed.add_field(name="Имеется бан на сервере", value=message, inline=False) #Количество в бане if "ban_list" in self.current and self.current["ban_list"]: embed.add_field(name="Был в бане", value=f"{len(self.current['ban_list'])} раз", inline=False) #Репорты if "reports" in self.current and self.current["reports"]: embed.add_field(name="Репорты", value=f"Отправлено: {self.current.get('reports',{}).get('created', 0)} раз\nЖаловались {self.current.get('reports',{}).get('accepted', 0)} раз") #Привязаные профили ранее if self.current.get("attached_discords", []): message_head = "" message = "" for d in self.current.get("attached_discords", []): if d['active'] == 1: message_head += f"<@{d['discord_id']}> | {utime2human(d['utime'])}\n" else: message += f"<@{d['discord_id']}> | {utime2human(d['utime'])}\n" if message_head: embed.add_field(name="Привязаный аккаунт Discord:", value=message_head, inline=False) if message: embed.add_field(name="История аккаунта Discord:", value=message, inline=False) return embed def __str__(self): if not self.current: raise NotLoadProfile message = self.current["steamids"]["community_url"] + "\n" if "play_on" in self.current and self.current["play_on"]: message += f"Сейчас играет на {self.stats['servers'][self.current['play_on']['server_id']]['name']}\n" message += "\n" #Последняя игра и игровое время self.lastplayAndGametime = {} if "lastplay" in self.current and self.current["lastplay"]: for maps in self.current["lastplay"].values(): for map_name, last_play in maps.items(): if not workshopmap2bsp(map_name) in self.lastplayAndGametime: self.lastplayAndGametime[workshopmap2bsp(map_name)] = {"total":0, "lastplay":0} self.lastplayAndGametime[workshopmap2bsp(map_name)]['lastplay'] = last_play if "gametime" in self.current and self.current["gametime"]: for maps in self.current["gametime"].values(): for map_name, play_time in maps.items(): if not workshopmap2bsp(map_name) in self.lastplayAndGametime: self.lastplayAndGametime[workshopmap2bsp(map_name)] = {"total":0, "lastplay":0} self.lastplayAndGametime[workshopmap2bsp(map_name)]["total"] = play_time if len(list(self.lastplayAndGametime.keys())) > 0: message += "Статистика игры:\n" for map_name, values in self.lastplayAndGametime.items(): message += f"{map_name}\n{human_TIME(values['total']) if values['total'] > 0 else 'Не играл'} / {utime2human(values['lastplay']) if values['lastplay'] > 0 else 'Не играл'}\n" message += "\n" #Далее идут проверка прав if "permition" in self.current and self.current["permition"]: message += f"Права: {self.current['permition']['status']} назначены {utime2human(self.current['permition']['u_timestamp']) if self.current['permition']['u_timestamp'] != 0 else 'с момента создания'}\n" if self.current['permition'].get('amount', 0) and self.current['permition'].get("u_timestamp", 0): message += f"Кончаются: {utime2human(self.current['permition']['u_timestamp'] + self.current['permition']['amount'])}\n" message += "\n" #Далее проверка бана if "ban" in self.current and self.current["ban"]: message += "ИМЕЕТСЯ БАН\n" message += f"Ник: {self.current['ban']['player_name']}\n" message += f"Причина: {self.current['ban']['ban_reason']}\n" message += f"Время: {utime2human(self.current['ban']['ban_utime'])}\n" message += f"Кто забанил: {self.current['ban']['banned_by']} | <@{self.current['ban']['admin_info']['discord_id']}>\n" if self.current['ban']['active'] == True: if self.current['ban']['ban_length'] == 0: message += "Данный бан навсегда!\n" else: message += f"Дата разбана: {utime2human(self.current['ban']['ban_utime'] + self.current['ban']['ban_length_seconds'])}\n" else: message += f"Кто разбанил: {'бан снялся со временем' if self.current['ban']['unbanned_by_id'] == 'STEAM_0:0:0' else self.current['ban']['unbanned_by_id']}\n" message += "\n" #Скок был в бане if "ban_list" in self.current and self.current["ban_list"]: message += f"Был в бане {len(self.current['ban_list'])} раз\n" message += "\n" #Количество репортво if "reports" in self.current and self.current["reports"]: message += f"Было отправлено {self.current.get('reports',{}).get('created', 0)} репортов\n Жаловались {self.current.get('reports',{}).get('accepted', 0)} раз\n" message += "\n" return message async def GetSteamIDOfProfile(self, any:str): async with aiohttp.ClientSession(cookies={"secretkey":os.getenv("BACKEND_SECRETKEY")}) as session: async with session.post(url=f"{os.getenv('BACKEND_URL')}/api/profile/steam", json = {"any":any}, ssl=False) as response: try: response = await response.json() except: response = None if response == None: raise CannotCastToSteamID return response async def GetProfile(self, steam64): async with aiohttp.ClientSession(cookies={"secretkey":os.getenv("BACKEND_SECRETKEY")}) as session: async with session.get(f"{os.getenv('BACKEND_URL')}/api/profile?steam64={steam64}", ssl=False) as response: return await response.json() ############### #admin commands ############### async def vip(self, amount): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/vip?steam64={self.steam64}&amount={amount}" async with session.post(url, ssl=False) as response: await response.text() if response.status == 409: return "Нельзя выдать випку по причине что пользователь имеет отличные правила от випа" elif response.status == 201: return "Випка была выдана" elif response.status == 205: return "Випка была продленна" elif response.status == 400: return "На том конце проишел хуй знает что" elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) async def unvip(self): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/vip?steam64={self.steam64}" async with session.delete(url, ssl=False) as response: await response.text() if response.status == 409: return "У пользователя есть права, но они не вип, так что хуй" elif response.status == 200: return "Удалены права" elif response.status == 404: return "У пользователя нет прав и так" elif response.status == 400: return "На том конце проишел хуй знает что" elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) async def kick(self, reason): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/kick?steam64={self.steam64}&reason={reason}" async with session.post(url, ssl=False) as response: result = await response.text() if response.status == 200: return "Кикнут с серверов" elif response.status == 404: raise NotFoundPlayerOnServer elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) async def mute(self): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/mute?steam64={self.steam64}" async with session.post(url, ssl=False) as response: result = await response.text() if response.status == 200: return "Выключен микрофон" elif response.status == 404: raise NotFoundPlayerOnServer elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) async def unmute(self): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/mute?steam64={self.steam64}" async with session.delete(url, ssl=False) as response: result = await response.text() if response.status == 200: return "Включен микрофон" elif response.status == 404: raise NotFoundPlayerOnServer elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) async def rcon(self, command, args): if not self.current: return "добродей дурачек забыл прогрузить профиль" if self.current.get("play_on", {}): server = self.current['play_on']['server_id'] player_id = self.current['play_on']['player_id'] final_command = f"{command} #{player_id} {args}" async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/rcon?srv={server}&command={final_command}" async with session.post(url, ssl=False) as response: res = await response.text() if response.status == 200: return res elif response.status == 404: raise NotFoundPlayerOnServer elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) else: raise NotFoundPlayerOnServer async def ban(self, reason, minutes): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/ban?steam64={self.steam64}&ban_reason={reason}&ban_length={minutes}" async with session.post(url, ssl=False) as response: ban_id = await response.text() if response.status in [201, 200]: return f"Игрок теперь забанен! Ид бана: #{ban_id}" elif response.status == 202: return f"Игрок уже в бане! Ид бана #{ban_id}" elif response.status == 404: raise NotFoundPlayerOnServer elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) async def unban(self): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/ban?steam64={self.steam64}" async with session.delete(url, ssl=False) as response: ban_id = await response.text() if response.status == 200: return f"Игрок теперь разбанен!" elif response.status == 404: return f"Игрок не в бане(" elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) async def foundAlts(self): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: url = f"{os.getenv('BACKEND_URL')}/api/admin/db/alt?steam64={self.steam64}" async with session.get(url, ssl=False) as response: data = await response.json() if response.status == 200: resp = "Ссылки на аккаунты:\n" for url in data: resp += f"{url}\n" return resp elif response.status == 404: raise NotFoundPlayerOnServer elif response.status == 403: raise LowPermition elif response.status == 406: raise AdminLowPermition raise UnknownBackendResponse(url, response) ############### #user command ############### async def report(self, reason): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.requester_steam64}) as session: async with session.post(f"{os.getenv('BACKEND_URL')}/api/profile/current/report?steam64={self.steam64}&text={reason}", ssl=False) as response: result = int(await response.text()) if result == 0: return "Игрок с таким именем не играет на серверах в данный момент..." elif result < 0: return f"Падажди, следующий репорт можно отправить только после: {-1 * result} секунд" else: return f"Репорт отправлен!" async def freevip(self): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY"), "steam64": self.steam64}) as session: async with session.post(f"{os.getenv('BACKEND_URL')}/api/profile/current/freevip", ssl=False, json = {"discord_id": await self.GetDiscordId(), "vk_id":0}) as response: result = int(await response.text()) if result == 0: return "Права на данном аккаунте уже имеются" elif result == 1: return "Развлекайся бро..." elif result > 1: return f"Ты не можешь получить бесплатную випку, стоит подождать {human_TIME(result)} с прошлой выдачи!" elif result < 0: return f"Чел... Тебе нужно еще наиграть на наших серверах {human_TIME(-1*result)} чтоб получить бесплатный вип!!!" else: return "Нихуя..." ############# #discord sync ############# async def GetDiscordId(self): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY")}) as session: async with session.get(f"{os.getenv('BACKEND_URL')}/api/discord/steam?steam64={self.steam64}", ssl = False) as response: try: discord_id = int(await response.text()) if response.status == 404: raise Exception#код в ахуй except: discord_id = 0 return discord_id async def CreateDiscordId(self, discord_id): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY")}) as session: async with session.post(f"{os.getenv('BACKEND_URL')}/api/discord?discord_id={discord_id}&steam64={self.steam64}", ssl = False) as response: result = await response.text() if response.status == 406: return False elif response.status == 201: return result else: return False async def RemoveDiscordId(self, discord_id): async with aiohttp.ClientSession(cookies={ "secretkey":os.getenv("BACKEND_SECRETKEY")}) as session: async with session.delete(f"{os.getenv('BACKEND_URL')}/api/discord?discord_id={discord_id}", ssl = False) as response: result = await response.text() if response.status == 406: return False elif response.status == 200: return result else: return False def workshopmap2bsp(map_name): return map_name.split('/')[-1:][0].split('.ugc')[0] def utime2human(utime): return datetime.fromtimestamp(utime).strftime('%H:%M:%S %d.%m.%Y') def human_TIME(seconds): m, s = divmod(int(seconds), 60) h, m = divmod(m, 60) d, h = divmod(h, 24) if not d: return "%d:%02d:%02d" % (h, m, s) elif d < 2: return "%d день %d:%02d:%02d" % (d ,h, m, s) else: return "%d дней %d:%02d:%02d" % (d ,h, m, s) def ban2message(ban): message = f"Ник: {ban['player_name']}\n" message += f"Причина: {ban['ban_reason']}\n" message += f"Время: {utime2human(ban['ban_utime'])}\n" try: message += f"Кто забанил: {ban['banned_by']} | <@{ban['admin_info']['discord_id']}>\n" except: pass #что выше надо править if ban['active'] == True: if ban['ban_length'] == 0: message += "Данный бан навсегда!\n" else: message += f"Дата разбана: {utime2human(ban['ban_utime'] + ban['ban_length_seconds'])}\n" return message