async def presense_load(self): # 1 = display number of servers, 2 = display total players/total maxplayers, 3 = display each server one by one every 10 minutes if len(self.server_list) == 0: activity_text = f'Command: {DGSM_PREFIX}server' if PRESENCE_TYPE <= 1: activity_text = f'{len(self.server_list)} game servers' elif PRESENCE_TYPE == 2: total_activeplayers = total_maxplayers = 0 for server in self.server_list: server_cache = ServerCache(server['addr'], server['port']) data = server_cache.get_data() if data and server_cache.get_status() == 'Online': total_activeplayers += int(data['players']) total_maxplayers += int(data['maxplayers']) activity_text = f'{total_activeplayers}/{total_maxplayers} active players' if total_maxplayers > 0 else '0 players' elif PRESENCE_TYPE >= 3: if self.current_display_server >= len(self.server_list): self.current_display_server = 0 server_cache = ServerCache(self.server_list[self.current_display_server]['addr'], self.server_list[self.current_display_server]['port']) data = server_cache.get_data() if data and server_cache.get_status() == 'Online': activity_text = f'{data["players"]}/{data["maxplayers"]} on {data["name"]}' if int(data["maxplayers"]) > 0 else '0 players' self.current_display_server += 1 if activity_text: await bot.change_presence(status=discord.Status.online, activity=discord.Activity(name=activity_text, type=3)) self.print_to_console(f'Discord presence updated | {activity_text}')
async def presence_load(self): # 1 = display number of servers, 2 = display total players/total maxplayers, 3 = display each server one by one every 10 minutes if len(self.server_list) == 0: activity_text = f'Command: {PREFIX}dgsm' if PRESENCE_TYPE <= 1: activity_text = f'{self.servers.get_distinct_server_count()} game servers' elif PRESENCE_TYPE == 2: total_activeplayers = total_maxplayers = 0 for server in self.server_list: server_cache = ServerCache(server["address"], server["port"]) data = server_cache.get_data() if data and server_cache.get_status() == 'Online': if data['players'].isdigit(): total_activeplayers = int(data['players']) total_maxplayers += int(data['maxplayers']) activity_text = f'{total_activeplayers}/{total_maxplayers} active players' if total_maxplayers > 0 else "0 players" elif PRESENCE_TYPE >= 3: if self.current_display_server >= len(self.server_list): self.current_display_server = 0 server_cache = ServerCache( self.server_list[self.current_display_server]["address"], self.server_list[self.current_display_server]["port"]) data = server_cache.get_data() if data and server_cache.get_status() == "Online": activity_text = f'{data["players"]}/{data["maxplayers"]} on {data["name"]}' if int( data["maxplayers"]) > 0 else "0 players" else: activity_text = None self.current_display_server += 1 if activity_text != None: try: await client.change_presence(status=discord.Status.online, activity=discord.Activity( name=activity_text, type=3)) self.print_to_console( f'Discord presence updated | {activity_text}') except Exception as e: self.print_to_console( f'ERROR: Unable to update presence.\n{e}')
def get_embed(self, server): # load server cache server_cache = ServerCache(server['addr'], server['port']) # load server data data = server_cache.get_data() if data: # load server status Online/Offline status = server_cache.get_status() emoji = (status == 'Online') and ':green_circle:' or ':red_circle:' if status == 'Online': if int(data['maxplayers']) <= int(data['players']): color = discord.Color.from_rgb(240, 71, 71) # red elif int(data['maxplayers']) <= int(data['players']) * 2: color = discord.Color.from_rgb(250, 166, 26) # yellew else: color = discord.Color.from_rgb(67, 181, 129) # green try: if 'color' in server: h = server['color'].lstrip('#') rgb = tuple(int(h[i:i + 2], 16) for i in (0, 2, 4)) color = discord.Color.from_rgb( rgb[0], rgb[1], rgb[2]) except Exception as e: self.print_to_console(e) else: color = discord.Color.from_rgb(32, 34, 37) # dark title = (data['password'] and ':lock: ' or '') + f'`{data["name"]}`' custom = ('custom' in server) and server['custom'] or None if custom and custom.strip(): embed = discord.Embed(title=title, description=custom, color=color) elif server['type'] == 'SourceQuery' and not custom: embed = discord.Embed( title=title, description= f'Connect: steam://connect/{data["addr"]}:{server["port"]}', color=color) else: embed = discord.Embed(title=title, color=color) embed.add_field(name=FIELD_STATUS, value=f'{emoji} **{status}**', inline=True) embed.add_field(name=f'{FIELD_ADDRESS}:{FIELD_PORT}', value=f'`{data["addr"]}:{data["port"]}`', inline=True) flag_emoji = ('country' in server) and ( ':flag_' + server['country'].lower() + f': {server["country"]}') or ':united_nations: Unknown' embed.add_field(name=FIELD_COUNTRY, value=flag_emoji, inline=True) embed.add_field(name=FIELD_GAME, value=data['game'], inline=True) embed.add_field(name=FIELD_CURRENTMAP, value=data['map'], inline=True) if status == 'Online': value = str(data['players']) # example: 20/32 if int(data['bots']) > 0: value += f' ({data["bots"]})' # example: 20 (2)/32 else: value = '0' # example: 0/32 embed.add_field(name=FIELD_PLAYERS, value=f'{value}/{data["maxplayers"]}', inline=True) if 'image_url' in server: image_url = str(server['image_url']) else: image_url = ( CUSTOM_IMAGE_URL and CUSTOM_IMAGE_URL.strip() ) and CUSTOM_IMAGE_URL or f'https://github.com/DiscordGSM/Map-Thumbnails/raw/master/{urllib.parse.quote(data["game"])}' image_url += f'/{urllib.parse.quote(data["map"])}.jpg' embed.set_thumbnail(url=image_url) else: # server fail to query color = discord.Color.from_rgb(240, 71, 71) # red embed = discord.Embed( title='ERROR', description=f'{FIELD_STATUS}: :warning: **Fail to query**', color=color) embed.add_field(name=f'{FIELD_ADDRESS}:{FIELD_PORT}', value=f'{server["addr"]}:{server["port"]}', inline=True) embed.set_footer( text= f'DiscordGSM v{VERSION} | 📺Game Server Monitor | Last update: ' + datetime.now().strftime('%a, %Y-%m-%d %I:%M:%S%p'), icon_url= 'https://github.com/DiscordGSM/DiscordGSM/raw/master/images/discordgsm.png' ) return embed
def get_embed(self, server): server_cache = ServerCache(server["address"], server["port"]) data = server_cache.get_data() cache_status = server_cache.get_status() # Evaluate fields try: lock = (server["locked"] if type(self.get_value(server, "locked")) == bool else data["password"] if type( self.get_value(data, "password")) == bool else False) title = self.get_value(server, "title") or self.get_value( data, "game") or self.get_value(server, "game") title = f':lock: {title}' if lock else f':unlock: {title}' description = self.get_value(server, "custom") status = (f':green_circle: **{FIELD_ONLINE}**' if cache_status == "Online" else f':red_circle: **{FIELD_OFFLINE}**' if cache_status == "Offline" and data is not False else f':yellow_circle: **{FIELD_UNKNOWN}**') hostname = self.get_value(server, "hostname") or self.get_value( data, "name") or SPACER players_string = self.determinePlayerString( server, data, cache_status) port = self.get_value(data, "port") address = self.get_value( server, "public_address" ) or self.get_value( data, "address" ) and port and f'{self.get_value(data, "address")}:{port}' or SPACER password = self.get_value(server, "password") country = self.get_value(server, "country") map = None if self.get_value( server, "map") == False else self.get_value( server, "map") or self.get_value(data, "map") image_url = self.get_value(server, "image_url") steam_id = self.get_value(server, "steam_id") direct_join = self.get_value(server, "direct_join") color = self.determineColor(server, data, cache_status) except Exception as e: self.print_to_console(f'Error Evaluate fields.\n{e}') # Build embed try: embed = (discord.Embed( title=title, description=description, color=color) if description else discord.Embed(title=title, color=color)) embed.add_field(name=FIELD_STATUS, value=status, inline=True) embed.add_field(name=FIELD_NAME, value=hostname, inline=True) embed.add_field(name=SPACER, value=SPACER, inline=True) embed.add_field(name=FIELD_PLAYERS, value=players_string, inline=True) embed.add_field(name=FIELD_ADDRESS, value=f'`{address}`', inline=True) if password is None: embed.add_field(name=SPACER, value=SPACER, inline=True) else: embed.add_field(name=FIELD_PASSWORD, value=f'`{password}`', inline=True) if country: embed.add_field(name=FIELD_COUNTRY, value=f':flag_{country.lower()}:', inline=True) if map and not country: embed.add_field(name=SPACER, value=SPACER, inline=True) if map: embed.add_field(name=FIELD_CURRENTMAP, value=map, inline=True) if map or country: embed.add_field(name=SPACER, value=SPACER, inline=True) if steam_id: if direct_join: if password: embed.add_field( name=FIELD_JOIN, value=f'steam://connect/{address}/{password}', inline=False) else: try: embed.add_field(name=FIELD_JOIN, value=f'steam://connect/{address}', inline=False) except Exception as e: self.print_to_console( f'Error Building embed 2.\n{e}') else: embed.add_field(name=FIELD_LAUNCH, value=f'steam://rungameid/{steam_id}', inline=False) if image_url: embed.set_thumbnail(url=image_url) embed.set_footer( text= f'DiscordGSM v.{VERSION} | Game Server Monitor | {FIELD_LASTUPDATE}: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}{SPACER}', icon_url=CUSTOM_IMAGE_URL) except Exception as e: self.print_to_console(f'Error Building embed.\n{e}') return embed
def get_embed(self, server): server_cache = ServerCache(server["address"], server["port"]) data = server_cache.get_data() cache_status = server_cache.get_status() # Evaluate fields try: lock = (server["locked"] if type(self.get_value(server, "locked")) == bool else data["password"] if type( self.get_value(data, "password")) == bool else False) # title = self.get_value(server, "title") or self.get_value(data, "game") or self.get_value(server, "game") # title = f':lock: {title}' if lock else f':unlock: {title}' description = self.get_value(server, "custom") status = (f':green_circle: **{FIELD_ONLINE}**' if cache_status == "Online" else f':red_circle: **{FIELD_OFFLINE}**' if cache_status == "Offline" and data is not False else f':yellow_circle: **{FIELD_UNKNOWN}**') hostname = self.get_value(server, "hostname") or self.get_value( data, "name") or SPACER players_string = self.determinePlayerString( server, data, cache_status) port = self.get_value(data, "port") address = self.get_value( server, "public_address" ) or self.get_value( data, "address" ) and port and f'{self.get_value(data, "address")}:{port}' or SPACER password = self.get_value(server, "password") country = self.get_value(server, "country") map = None if self.get_value( server, "map") == False else self.get_value( server, "map") or self.get_value(data, "map") map_size = self.get_value(data, "mapsize") image_url = self.get_value(server, "image_url") steam_id = self.get_value(server, "steam_id") direct_join = self.get_value(server, "direct_join") color = self.determineColor(server, data, cache_status) except Exception as e: self.print_to_console(f'Error Evaluate fields.\n{e}') # Build embed try: embed = discord.Embed(title=hostname, color=color) # embed = (discord.Embed(title=title, description=description, color=color) if description # else discord.Embed(title=title, color=color)) global FIELD_STATUS, FIELD_CURRENTMAP, FIELD_MAPSIZE, FIELD_PLAYERS, FIELD_COUNTRY, FIELD_LASTUPDATE, FIELD_JOIN if server['channel'] == 743816489278373950: FIELD_STATUS = 'Trạng Thái' FIELD_CURRENTMAP = 'Map Hiện Tại' FIELD_MAPSIZE = 'Kích Cỡ' FIELD_PLAYERS = 'Người Chơi' FIELD_COUNTRY = 'Host ở' FIELD_LASTUPDATE = 'Update Lúc' FIELD_JOIN = 'Tham gia Máy Chủ' embed.add_field(name=FIELD_STATUS, value=status, inline=True) embed.add_field(name=SPACER, value=SPACER, inline=True) embed.add_field(name=FIELD_PLAYERS, value=players_string, inline=True) embed.add_field(name=FIELD_ADDRESS, value=f'`{address}`', inline=True) if password is None: embed.add_field(name=SPACER, value=SPACER, inline=True) else: embed.add_field(name=FIELD_PASSWORD, value=f'`{password}`', inline=True) if country: embed.add_field(name=FIELD_COUNTRY, value=f':flag_{country.lower()}:', inline=True) if map and not country: embed.add_field(name=SPACER, value=SPACER, inline=True) if map: embed.add_field(name=FIELD_CURRENTMAP, value=map, inline=True) if map or country: embed.add_field(name=SPACER, value=SPACER, inline=True) if map_size: embed.add_field(name=FIELD_MAPSIZE, value=map_size, inline=True) if steam_id: if direct_join: if password: embed.add_field( name=FIELD_JOIN, value= f'steam://connect/{data["address"]}:{port}/{password}', inline=False) else: embed.add_field( name=FIELD_JOIN, value=f'steam://connect/{data["address"]}:{port}', inline=False) else: embed.add_field(name=FIELD_LAUNCH, value=f'steam://rungameid/{steam_id}', inline=False) if server['game'] == "Forgotten Hope 2": url = f"fh2://{data['address']}:{data['port']}" embed.add_field(name=FIELD_JOIN, value=f"<{url}>") image_url = requote_uri( 'https://raw.githubusercontent.com/radiosmersh/Map-Thumbnails/master/Forgotten Hope 2/%s.png' % data["map"]) if image_url: embed.set_image(url=image_url) if server['channel'] == 743816489278373950: time_utc = datetime.utcnow() timezone_local = timezone('Asia/Saigon') time_local = utc.localize(time_utc).astimezone(timezone_local) embed.set_footer( text= f'{FIELD_LASTUPDATE}: {time_local.strftime("%Y-%m-%d %H:%M:%S")}{SPACER}', icon_url=CUSTOM_IMAGE_URL) else: embed.set_footer( text= f'{FIELD_LASTUPDATE}: {datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")}{SPACER}', icon_url=CUSTOM_IMAGE_URL) if server['channel'] == 743816489278373950: FIELD_STATUS = os.getenv("DGSM_FIELD_STATUS") or "Status" FIELD_CURRENTMAP = os.getenv("DGSM_FIELD_CURRENTMAP") or "Map" FIELD_MAPSIZE = os.getenv("DSGM_FIELD_MAPSIZE") or "Map Size" FIELD_PLAYERS = os.getenv("DGSM_FIELD_PLAYERS") or "Players" FIELD_COUNTRY = os.getenv("DGSM_FIELD_COUNTRY") or "Country" FIELD_LASTUPDATE = os.getenv( "DGSM_FIELD_LASTUPDATE") or "Last Update" FIELD_JOIN = os.getenv("DGSM_FIELD_JOIN") or "Join Server" except Exception as e: self.print_to_console(f'Error Building embed.\n{e}') return embed
def get_embed(server): # load server cache server_cache = ServerCache(server['addr'], server['port']) # load server data data = server_cache.get_data() if data: # load server status Online/Offline status = server_cache.get_status() if status == 'Online': emoji = ':green_circle:' if data['maxplayers'] <= data['players']: color = discord.Color.from_rgb(240, 71, 71) # red elif data['maxplayers'] <= data['players'] * 2: color = discord.Color.from_rgb(250, 166, 26) # yellew else: color = discord.Color.from_rgb(67, 181, 129) # green else: emoji = ':red_circle:' color = discord.Color.from_rgb(32, 34, 37) # dark title = (data['password'] and ':lock: ' or '') + data["name"] description = ('custom' in server) and server['custom'] or '' if server['type'] == 'SourceQuery': embed = discord.Embed(title=title, description=f'Connect: steam://connect/{data["addr"]}:{server["port"]}\n' + description, color=color) elif description.strip(): embed = discord.Embed(title=title, description=description, color=color) else: embed = discord.Embed(title=title, color=color) embed.add_field(name=f'{settings["fieldname"]["status"]}', value=f'{emoji} **{status}**', inline=True) embed.add_field(name=f'{settings["fieldname"]["address"]}:{settings["fieldname"]["port"]}', value=f'`{data["addr"]}:{data["port"]}`', inline=True) flag_emoji = ('country' in server) and (':flag_' + server['country'].lower() + f': {server["country"]}') or ':united_nations: Unknown' embed.add_field(name=f'{settings["fieldname"]["country"]}', value=flag_emoji, inline=True) embed.add_field(name=f'{settings["fieldname"]["game"]}', value=f'{data["game"]}', inline=True) embed.add_field(name=f'{settings["fieldname"]["currentmap"]}', value=f'{data["map"]}', inline=True) if status == 'Online': value = f'{data["players"]}' # example: 20/32 if data['bots'] > 0: value += f' ({data["bots"]})' # example: 20 (2)/32 else: value = '0' # example: 0/32 embed.add_field(name=f'{settings["fieldname"]["players"]}', value=f'{value}/{data["maxplayers"]}', inline=True) if 'image_url' in server: image_url = str(server['image_url']) else: image_url = f'https://github.com/BITFOR/Map-Thumbnails/raw/master/{urllib.parse.quote(data["game"])}/{urllib.parse.quote(data["map"])}.jpg' embed.set_thumbnail(url=image_url) else: # server fail to query color = discord.Color.from_rgb(240, 71, 71) # red embed = discord.Embed(title='ERROR', description=f'{settings["fieldname"]["status"]}: :warning: **Fail to query**', color=color) embed.add_field(name=f'{settings["fieldname"]["port"]}', value=f'{server["addr"]}:{server["port"]}', inline=True) embed.set_footer(text=f'DiscordGSM v{VERSION} | Monitor game server | Last update: ' + datetime.now().strftime('%a, %Y-%m-%d %I:%M:%S%p'), icon_url='https://github.com/BITFOR/DiscordGSM/raw/master/images/discordgsm.png') return embed
async def print_servers(): next_presence_update_time = 0 total_players = total_maxplayers = 0 current_servers = players = maxplayers = 0 server_name = '' edit_message_error_count = 0 next_message_update_time = 0 # 1 = display number of servers, 2 = display total players/total maxplayers, 3 = display each server one by one every 10 minutes presence_type = settings.get('presence_type', 3) if presence_type <= 1: hints = f'number of servers' elif presence_type == 2: hints = f'total players/total maxplayers' elif presence_type >= 3: hints = f'each server one by one every 10 minutes' print(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + f' Presence update type: {presence_type} | display {hints}') while True: # don't continue when servers is refreshing if not is_refresh: # edit error with some reasons (maybe messages edit limit?), anyway servers refresh will fix this issue if edit_message_error_count >= 20: edit_message_error_count = 0 # refresh discord servers list await refresh_servers_list() print(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + ' Message ERROR reached, servers list refreshed') continue if int(datetime.utcnow().timestamp()) >= next_message_update_time: # query servers and save cache game_servers.query() if current_servers >= len(servers): current_servers = 0 # edit embed updated_count = 0 for i, server in zip(range(len(servers)), servers): # load server cache. If the data is the same, don't update the discord message server_cache = ServerCache(server['addr'], server['port']) data = server_cache.get_data() if data and server_cache.get_status() == 'Online': # save total players and total maxplayers total_players += data['players'] total_maxplayers += data['maxplayers'] # save players and maxplayers if i == current_servers: players = data['players'] maxplayers = data['maxplayers'] server_name = data['name'] # if the server is fail to query or offline elif i == current_servers: current_servers += 1 if current_servers >= len(servers): current_servers = 0 try: await messages[i].edit(embed=get_embed(server)) updated_count += 1 except: edit_message_error_count += 1 print( datetime.now().strftime('%Y-%m-%d %H:%M:%S') + f' ERROR: message {i} fail to edit, message deleted or no permission. Server: {server["addr"]}:{server["port"]}' ) # delay server query delay = int(settings['refreshrate']) if int( settings['refreshrate'] ) > MIN_REFRESH_RATE else MIN_REFRESH_RATE next_message_update_time = int( datetime.utcnow().timestamp()) + delay print(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + f' {updated_count} messages updated') # update presence if int(datetime.utcnow().timestamp()) >= next_presence_update_time: if len(servers) == 0: activity_text = f'Command: {settings["prefix"]}dgsm' elif presence_type <= 1: activity_text = f'{len(servers)} game servers' elif presence_type == 2: activity_text = f'{total_players}/{total_maxplayers} active players' if total_maxplayers > 0 else '0 players' elif presence_type >= 3: activity_text = f'{players}/{maxplayers} on {server_name}' if maxplayers > 0 else '0 players' if activity_text: current_servers += 1 next_presence_update_time = int( datetime.utcnow().timestamp()) + 10 * 60 await bot.change_presence(status=discord.Status.online, activity=discord.Activity( name=activity_text, type=3)) print(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + f' Presence updated | {activity_text}') await asyncio.sleep(1)