def _get_server_info_worker(cls, address_list, query_timeout: float = 1.0, full_update: bool = False) -> list: server_info_ls: List[dict] = list() for address in address_list: try: # -- Get Server info info = a2s.info(address, query_timeout) info.players = list() # -- Get Player Info if requested if info and full_update: try: players = a2s.players(address, query_timeout * 4) info.players = cls._serialize_player_info(players) info.player_count = len(info.players) except Exception as exc: logging.error( 'Error while querying for player info: %s', exc) # -- Remove AI from player count info.player_count = max(0, info.player_count - info.bot_count) # -- Serialize data to JSON dict if info: server_info_ls.append( cls._source_info_to_server_dict(info, address)) except Exception as exc: logging.error('Error while querying for server info: %s', exc) return server_info_ls
def refresh(): while True: logging.info("Refreshing server info...") address = (os.environ.get("SERVER_ADDRESS", "n1-atl-pterodactyl.graysons.network"), int(os.environ.get("SERVER_PORT", "2457"))) global last_active global server_online players = [] try: players = a2s.players(address, timeout=2) server_online = True logging.info("Server is online") except socket.timeout: logging.warning("Failed to get players, server offline") server_online = False last_active = datetime.datetime.now() if len(players) > 0: last_active = datetime.datetime.now() logging.info("There are players online") if last_active < datetime.datetime.now() - datetime.timedelta( minutes=IDLE_MINUTES_SHUTOFF): try: stop_server() except Exception as e: logging.critical("Failed to stop server.") logging.critical(str(e)) time.sleep(5)
async def server(channel): """Checks if the server is running or not. Parameters ---------- channel : str Chat channel of the server Returns ------- Server info if server is online otherwise False. """ for serverdict in server_list: if serverdict["commands_channel"] == str(channel) or serverdict["admin_channel"] == str(channel)\ or serverdict["chat_channel"] == str(channel): address = serverdict["server_address"] break try: svr_info = a2s.info(address, 1.0) svr_players = a2s.players(address) return {"server_info": svr_info, "server_players": svr_players} except Exception as e: logging.warning( f'[Pyre-Bot:Commands][{datetime.now(tz).strftime(t_fmt)}] Error checking server status: {e}' ) return False
async def players_logic(ctx, address, bot): data = address.split(":") try: info = a2s.players((data[0], int(data[1]))) except socket.timeout: return await ctx.send("Server timeout! Check the IP:Port") except socket.gaierror: return await ctx.send("Resolution error! Check the IP:Port") except IndexError: return await ctx.send("Please format your command like: `" + get_prefix(bot, ctx.guild.id) + "pquery 144.12.123.51:27017`") except a2s.BufferExhaustedError as e: return await ctx.send( "Buffer exhausted! Please confirm that the server has the following configuration" ":\n```host_name_store 1\nhost_info_show 1\nhost_players_show 2```" ) if not info or len(info) == 0: return await ctx.send("Server is empty!") for d in info: seconds = d.duration % (24 * 3600) hour = seconds // 3600 seconds %= 3600 minutes = seconds // 60 seconds %= 60 d.duration = "%d:%02d:%02d" % (hour, minutes, seconds) table = BeautifulTable() table.set_style(BeautifulTable.STYLE_BOX) for player in info: name = player.name[0:24] if name == "": name = "Connecting..." table.rows.append([name, player.duration, player.score]) table.columns.header = ["Name", "Duration", "Score"] if len(str(table)) > 1900: r = requests.post("https://www.hastepaste.com/api/create", data={ "text": str(table), "raw": "false" }) if r.status_code == 200: return await ctx.send( "Too many players for discord! See the players here: " + r.text) else: return await ctx.send( "Your server has too many players to post in Discord, but our HastePaste request " "failed. Please try again later, or contact support.") return await ctx.send("```r\n" + str(table) + "```")
def query(self): """ Query the steam server """ self.__playerList = [] # clear the playerList serverAddress = (self.__serverIP, self.__queryPort) try: info = a2s.info(serverAddress) if self.__nameOverride == False: self.__name = info.server_name if self.__gameOverride == False: self.__game = info.game self.__gameType = info.game # self.__decodeGameType("{server_tags}".format(**info)) self.__map = info.map_name self.__currentPlayers = info.player_count self.__maxPlayers = info.max_players for player in a2s.players(serverAddress): self.__playerList.append(player.name) self.__writeToDictionary() # except valve.source.messages.BrokenMessageError as err: # print(err) # if self.__port is not None: # print("Server " + str(self.__serverIP) + ":" + str(self.__port) + " exists, but " # + str(self.__queryPort) + " is not the correct query port.") # else: # print("Server " + str(self.__serverIP) + " exists, but " # + str(self.__queryPort) + " is not the correct query port.") # # give the data dict for the server the minimum amount of data needed to create a ServerInfo object # self.__dataDict["Status"] = "Offline" # self.__dataDict["Name"] = self.getName() # self.__dataDict["Game"] = self.getGame() except Exception as err: # python-a2s error handling is less than stellar, so this is as good as I can get it print(err) if self.__port is not None: print( "Server \"" + str(self.__serverIP) + " " + str(self.__name) + ":" + str(self.__port) + "\" is either offline, is not a source server, or does not exist" ) else: print( "Server \"" + str(self.__serverIP) + " " + str(self.__name) + "\" is either offline, is not a source server, or does not exist" ) # give the data dict for the server the minimum amount of data needed to create a ServerInfo object self.__dataDict["Status"] = "Offline" self.__dataDict["Name"] = self.getName() self.__dataDict["Game"] = self.getGame()
def server_player_count(server): """ The amount of players that are actively loaded in to the server. Done this way since the attribute of a2s.players includes players in queue. :param the server a2s server address that will be queried: :return: """ serverplayers = a2s.players(server) players = [] for player in serverplayers: if player.name != "": players.append(player) return len(players)
def get_game_info(self): info = a2s.info(self.address) players = a2s.players(self.address) serv_details = { 'serv_name': info.server_name, 'map': info.map_name, 'player_count': info.player_count, 'max_players': info.max_players, 'bot_count': info.bot_count, 'ping': info.ping, "players": players } return serv_details
def read_server_usernames(lines: List[str]) -> Set: """ connects to the latest server and returns the users connected to it """ latest_connection: str = [a for a in lines if re.match(server_re, a)][-1] server_str = latest_connection.split()[-1].split(":") server = (server_str[0], int(server_str[1])) names = set() try: names.update({p.name for p in a2s.players(server)}) except socket.timeout: print("tf2 server connection timeout") return names
async def query_players(self, ctx): ip = await self.config.guild(ctx.guild).ip() query_port = await self.config.guild(ctx.guild).query_port() if ip and query_port: try: return a2s.players((ip, int(query_port)), 2) except socket.timeout: await ctx.send("Connection timed out to server.") return None except socket.gaierror: await ctx.send("Invalid host address.") return None else: await ctx.send("IP and Port must be set.") return None
def get_server_data(server): players = None serverinfo = None for x in range(2): try: players = a2s.players(server) break except: # probably socket.timeout... pass if players: for x in range(2): try: serverinfo = a2s.info(server) break except: # probably socket.timeout... pass return (players, serverinfo)
def get(self): try: server_info = a2s.info((self.ip_address, self.server_port )) self.player_list = a2s.players((self.ip_address, self.server_port)) self.server_name = server_info.server_name self.curr_map = server_info.map_name.split('/')[-1] self.players = str(server_info.player_count) + '/' + str(server_info.max_players) self.ping = str(int((server_info.ping* 1000))) + 'ms' except: print('Server down :(') self.server_name = 'Server down :(' self.curr_map = 'Unknown' self.players = '0' self.playerstats = 'Unknown' self.ping = '999ms'
async def info(self): server_info = a2s.info(self.address, 1.0) server_players = a2s.players(self.address) # Creates the string of player names used in the embed player_names = [] for player in server_players: player_names.append(player.name) player_names = ("\n".join(map(str, player_names))) # Update server variables self.name = str(server_info.server_name) self.players = player_names self.player_num = server_info.player_count self.max_players = server_info.max_players return {"server_info": server_info, "server_players": server_players}
async def update_now_playing(): await client.wait_until_ready() while not client.is_closed(): # hl2dm players_hl2 = (a2s.players(address_hl2dm)) player_count_hl2 = len(players_hl2) await client.change_presence(activity=discord.Activity( type=discord.ActivityType.watching, name="{} players in HL2:DM".format(player_count_hl2))) await asyncio.sleep(10) # tf2 players_tf2 = (a2s.players(address_tf2)) player_count_tf2 = len(players_tf2) await client.change_presence(activity=discord.Activity( type=discord.ActivityType.watching, name="{} players in TF2".format(player_count_tf2))) await asyncio.sleep(10) # Arma3 players_arma3 = (a2s.players(address_arma3)) player_count_arma3 = len(players_arma3) await client.change_presence(activity=discord.Activity( type=discord.ActivityType.watching, name="{} players in Arma 3".format(player_count_arma3))) await asyncio.sleep(10) while not client.is_closed(): #hl2dm players_hl2 = (a2s.players(address_hl2dm)) player_count_hl2 = len(players_hl2) await client.change_presence(activity=discord.Activity( type=discord.ActivityType.watching, name="{} players in HL2:DM".format(player_count_hl2))) await asyncio.sleep(10) #tf2 players_tf2 = (a2s.players(address_tf2)) player_count_tf2 = len(players_tf2) await client.change_presence(activity=discord.Activity( type=discord.ActivityType.watching, name="{} players in TF2".format(player_count_tf2))) await asyncio.sleep(10) #Arma3 players_arma3 = (a2s.players(address_arma3)) player_count_arma3 = len(players_arma3) await client.change_presence(activity=discord.Activity( type=discord.ActivityType.watching, name="{} players in Arma 3".format(player_count_arma3))) await asyncio.sleep(10)
def servers_detail(request, id): obj = get_object_or_404(Servers, id=id) try: s = a2s.info((obj.ip, obj.port)) p = a2s.players((obj.ip, obj.port)) for i in p: i.duration = time.strftime("%H:%M:%S", time.gmtime(i.duration)) except socket.gaierror: raise Http404 except socket.timeout: raise Http404 return render(request, 'servers/servers_detail.html', { 'addr': f'{obj.ip}:{obj.port}', 'players': p, 'server': s })
def get_status(query_host: str, query_port: int) -> Dict: status = { "last_status_update": datetime.utcnow().replace(tzinfo=timezone.utc), "error": None, } try: info = a2s.info((query_host, query_port)) players = a2s.players((query_host, query_port)) except Exception as e: status.update({"error": e}) else: status.update({ "server_name": info.server_name, "server_type": info.server_type, "platform": info.platform, "player_count": len(players), "password_protected": info.password_protected, "vac_enabled": info.vac_enabled, "port": info.port, "steam_id": info.steam_id, "keywords": info.keywords, "game_id": info.game_id, "players": [{ "name": pl.name, "score": pl.score, "duration": pl.duration } for pl in players], }) return status
def update_players(self): #a2s = valve.source.a2s.ServerQuerier((self.host, self.port)) try: players = a2s.players((self.host, self.port)) self.up = True self.save() except: self.up = False self.save() return False player_models = [] for player in players: player = dict(player) player_models.append(Player( server=self, name=player['name'], score=player['score'], duration=player['duration'] )) self.player_set.all().delete() Player.objects.bulk_create(player_models) return True
def update_players(self): try: self.players = a2s.players(self.address) except (socket.timeout, OSError, a2s.exceptions.BrokenMessageError): print("%s: error updating players" % self.name) self.players = None
async def on_message(message): # we do not want the bot to reply to itself if message.author == client.user: return #get the channel the message was sent in channel = message.channel # Everything in this if-statement is for universe-admins and universe-mods only: if staff[0] in [y.id for y in message.author.roles ] or staff[1] in [y.id for y in message.author.roles]: if message.content.startswith('!foradminsonly'): msg = '{0.author.mention} is an admin'.format(message) await channel.send(msg) #await channel.send(message.channel, msg) if message.content.startswith('!whitelist add'): content = message.content.split() msg = 'Whitelisting {}'.format(content[2], message) await channel.send(msg) whitelistingOutput = subprocess.check_output( [whitelistScript, content[2]], stderr=subprocess.STDOUT).decode('utf-8') msg = 'Output terminal: {}'.format(whitelistingOutput, message) await channel.send(msg) if message.content.startswith('!ip'): ipOutput = subprocess.check_output( [curl, ipsite], stderr=subprocess.STDOUT).decode('utf-8') msg = 'Output terminal: {}'.format(ipOutput, message) await channel.send(msg) if "!HeilHansi" in message.content: msg = 'Danke schön {0.author.mention}! https://wetfjord.eu/heilhansi.png '.format( message) await channel.send(msg) if "!ComradeHansi" in message.content: comrade_list = [ 'Yes comrade?', 'Heil H... Stalin!', 'knock knock who\'s there? COMRADE HANSI!', 'cyka blyat {}'.format(message.author.mention) ] comrade_item = random.choice(comrade_list) msg = '{} https://wetfjord.eu/comradehansi.png '.format( comrade_item, message) await channel.send(msg) ###### non-admin commands: ###### if "hansi sucks" in message.content: msg = 'You said f*****g wut m8?! Fight me bitch'.format(message) await channel.send(msg) if "!commanderhansi" in message.content: commander_list = [ 'Yes comrade?', 'Well no shit. What\'ve we\'ve got here? A f*****g comedian, Private Joker.', 'knock knock who\'s there? COMMANDER HANSI!', 'I bet you\'re the kind of guy that would f-ck a person in the ass and not even have the goddamn common courtesy to give him a reach-around. I\'ll be watching you {}' .format(message.author.mention) ] commander_item = random.choice(commander_list) msg = ' https://wetfjord.eu/commanderhansi.png {}'.format( commander_item, message) await channel.send(msg) ###### Specific channels: ###### ##hl2:dm & tf2## if message.channel.id == 237233849820512267: if message.content.startswith('!on_hl2'): players = (a2s.players(address_hl2dm)) player_count = len(players) players_and_score = "" for player in players: playtime_minutes = player.duration / 60 players_and_score += player.name + "\t \t" + str( player.score) + "\t \t" + str(playtime_minutes) + "\n" msg = '``` Players online: {} \n Name \t \t Score \t \t Playtime (minutes) \n {} ```'.format( player_count, players_and_score) await channel.send(msg) if message.content.startswith('!on_tf2'): players = (a2s.players(address_tf2)) player_count = len(players) players_and_score = "" for player in players: playtime_minutes = player.duration / 60 players_and_score += player.name + "\t \t" + str( player.score) + "\t \t" + str(playtime_minutes) + "\n" msg = '``` Players online: {} \n Name \t \t Score \t \t Playtime (minutes) \n {} ```'.format( player_count, players_and_score) await channel.send(msg) ##Arma3## if message.channel.id == 250269739220336642: if message.content.startswith('!on'): players = (a2s.players(address_arma3)) game_info = (a2s.info(address_arma3)) player_count = len(players) players_and_score = "" for player in players: playtime_minutes = player.duration / 60 players_and_score += player.name + "\t \t" + str( player.score) + "\t \t" + str(playtime_minutes) + "\n" msg = '``` Map: {} \n Game: {} \n \n Players online: {} \n Name \t \t Score \t \t Playtime (minutes) \n {} ```'.format( game_info.map_name, game_info.game, player_count, players_and_score) await channel.send(msg)
def get_players(self): return a2s.players(self.address)
import datetime import time import a2s import csv wantedday = 18 addr = ("66.70.214.118", 27015) while True: if str(datetime.datetime.now().strftime("%d")) == wantedday - 1: print('incorrect day') time.sleep(10) continue elif str(datetime.datetime.now().strftime("%d")) == wantedday + 1: break try: pl = len(a2s.players(addr)) except: pl = 0 curtime = datetime.datetime.now().strftime("%I:%M %p") print(curtime,pl) with open('playercts.csv', mode='a+') as playerctfile: player_writer = csv.writer(playerctfile, delimiter=',') player_writer.writerow([str(curtime), pl]) time.sleep(1800)
def query(self): """Queries data through a2s and returns a QueryResponse.""" info = a2s.info(self.address) users = a2s.players(self.address) return QueryResponse(info, users)
def get_players(self): try: return a2s.players(address) except (socket.timeout, OSError, a2s.exceptions.BrokenMessageError): return None
def get_match_data(self, address: str, modes: List[str], usernames: Optional[Set[str]] = None, allow_network_errors: bool = True) -> Dict[str, str]: rate_limit: int = settings.get('server_rate_limit') time_since_last: float = time.time() - self.last_server_request_time if time_since_last < rate_limit and self.last_server_request_address == address: self.log.debug( f"Skipping getting server data ({round(time_since_last, 1)} < {rate_limit}), persisting {self.last_server_request_data}" ) return self.last_server_request_data else: self.last_server_request_time = time.time() self.last_server_request_address = address self.log.debug( f"Getting match data from server ({address}) with mode(s) {modes}") if ':' not in address or ' ' in address: if address: self.log.error(f"Server address ({address}) is invalid") else: self.log.debug(f"Server address is blank, assuming hosting") self.last_server_request_data = unknown_data(self.loc, modes) self.last_server_request_time -= rate_limit # ignores rate limit return self.last_server_request_data ip: str ip_socket: str ip, ip_socket = address.split(':') server_data: Dict[str, str] = {} need_server_info: bool = 'Player count' in modes or 'Server name' in modes try: if need_server_info: server_info = a2s.info((ip, int(ip_socket)), timeout=settings.get('request_timeout')) # there's a decent amount of extra data here that isn't used but could be (bot count, tags, etc.) if 'Kills' in modes: players_info = a2s.players( (ip, int(ip_socket)), timeout=settings.get('request_timeout')) except socket.timeout: if not allow_network_errors: raise if len(self.last_server_request_data) == len(modes): self.log.debug( "Timed out getting server info, persisting previous data") else: self.log.debug("Timed out getting server info") self.last_server_request_data = unknown_data(self.loc, modes) self.last_server_request_time -= rate_limit return self.last_server_request_data except (a2s.BrokenMessageError, a2s.BrokenMessageError, socket.gaierror, ConnectionRefusedError, ConnectionResetError, OSError) as error: if isinstance(error, OSError) and '[WinError 10051]' not in str(error): raise if not allow_network_errors: raise self.log.error( f"Couldn't get server info: {traceback.format_exc()}") self.last_server_request_data = unknown_data(self.loc, modes) self.last_server_request_time -= rate_limit return self.last_server_request_data if need_server_info: # do some validation, probably not worth doing an extra request each time if only using kills mode if server_info.protocol != 17: self.log.error( f"Server protocol is {server_info.protocol}, not 17") if server_info.game_id != 440: self.log.error( f"Server game ID is {server_info.game_id}, not 440") if server_info.folder != 'tf': self.log.error(f"Server game is {server_info.folder}, not tf") if 'Server name' in modes: server_name_formatted: str = cleanup_server_name( server_info.server_name) self.log.debug(f"Got server name: \"{server_name_formatted}\"") server_data['server_name'] = server_name_formatted if 'Player count' in modes: if 'valve' in server_info.keywords: max_players: int = 24 else: max_players = server_info.max_players player_count: str = self.loc.text("Players: {0}/{1}").format( server_info.player_count, max_players) self.log.debug(f"Got player count from server: \"{player_count}\"") server_data['player_count'] = player_count if 'Kills' in modes: kills: str = "" if not usernames: self.log.error("Trying to get kills data without usernames") usernames = set() for player in players_info: if player.name in usernames: kills: str = self.loc.text("Kills: {0}").format( player.score) self.log.debug(f"Got kill count from server: \"{kills}\"") break if not kills: self.log.debug( "User doesn't seem to be in the server, assuming still loading in" ) kills = self.loc.text("Kills: {0}").format(0) self.last_server_request_time -= rate_limit server_data['kills'] = kills self.last_server_request_data = server_data return self.last_server_request_data