Ejemplo n.º 1
0
class DNSProxy(SocketServer.ThreadingMixIn, SocketServer.UDPServer):
    SocketServer.ThreadingMixIn.daemon_threads = True
    allow_reuse_address = True

    def __init__(self, address=("0.0.0.0", 53), VERBOSE=2):
        self.VERBOSE = VERBOSE
        print "listening at:", address
        SELF = self

        class ProxyHandle(SocketServer.BaseRequestHandler):
            # Ctrl-C will cleanly kill all spawned threads
            daemon_threads = True
            # much faster rebinding
            allow_reuse_address = True

            def handle(self):
                data = self.request[0]
                socket = self.request[1]
                addr = self.client_address
                DNSProxy.transfer(SELF, data, addr, socket)

        SocketServer.UDPServer.__init__(self, address, ProxyHandle)

    def loadConfig(self, config):
        self.DNSS = config.DNSS
        self.servers = Servers()
        for s in self.DNSS:
            assert len(s) == 3
            ip, port, type_of_server = s
            self.servers.addDNSServer(DNSServer(ip, port, type_of_server))
        self.WHITE_DNSS = config.WHITE_DNSS
        for ws in self.WHITE_DNSS:
            assert len(ws) == 4
            ip, port, type_of_server, white_list = ws
            self.servers.addWhiteDNSServer(DNSServer(ip, port, type_of_server, white_list))


    def transfer(self, query_data, addr, server):
        if not query_data: return
        domain = bytetodomain(query_data[12:-4])
        qtype = struct.unpack('!h', query_data[-4:-2])[0]
        print 'domain:%s, qtype:%x, thread:%d' % \
              (domain, qtype, threading.activeCount())
        sys.stdout.flush()
        response = None
        for i in range(9):
            response, dnsserv = self.servers.query(query_data)
            if response:
                # udp dns packet no length
                server.sendto(response[2:], addr)
                if int(self.VERBOSE) > 0:
                    dnsserv.showInfo(query_data, 0)
                    dnsserv.showInfo(response[2:], 1)
                break
        if response is None:
            print "[ERROR] Tried 9 times and failed to resolve %s" % domain
        return
Ejemplo n.º 2
0
class DNSProxy(SocketServer.ThreadingMixIn, SocketServer.UDPServer):
    SocketServer.ThreadingMixIn.daemon_threads = True
    allow_reuse_address = True

    def __init__(self, address=("0.0.0.0", 53), VERBOSE=2):
        self.VERBOSE = VERBOSE
        print "listening at:", address
        SELF = self

        class ProxyHandle(SocketServer.BaseRequestHandler):
            # Ctrl-C will cleanly kill all spawned threads
            daemon_threads = True
            # much faster rebinding
            allow_reuse_address = True

            def handle(self):
                data = self.request[0]
                socket = self.request[1]
                addr = self.client_address
                DNSProxy.transfer(SELF, data, addr, socket)

        SocketServer.UDPServer.__init__(self, address, ProxyHandle)

    def loadConfig(self, config):
        self.DNSS = config.DNSS
        self.servers = Servers()
        for s in self.DNSS:
            assert len(s) == 3
            ip, port, type_of_server = s
            self.servers.addDNSServer(DNSServer(ip, port, type_of_server, self.VERBOSE))
        self.WHITE_DNSS = config.WHITE_DNSS
        for ws in self.WHITE_DNSS:
            assert len(ws) == 4
            ip, port, type_of_server, white_list = ws
            self.servers.addWhiteDNSServer(DNSServer(ip, port, type_of_server, self.VERBOSE, white_list))


    def transfer(self, query_data, addr, server):
        if not query_data: return
        domain = bytetodomain(query_data[12:-4])
        qtype = struct.unpack('!h', query_data[-4:-2])[0]
        #print 'domain:%s, qtype:%x, thread:%d' % (domain, qtype, threading.activeCount())
        sys.stdout.flush()
        response = None
        for i in range(9):
            response = self.servers.query(query_data)
            if response:
                # udp dns packet no length
                server.sendto(response[2:], addr)
                break
        if response is None:
            print "[ERROR] Tried 9 times and failed to resolve %s" % domain
        return
Ejemplo n.º 3
0
class DiscordGSM():
    def __init__(self, bot):
        print('\n----------------')
        print('Github: \thttps://github.com/DiscordGSM/DiscordGSM')
        print('Discord:\thttps://discord.gg/Cg4Au9T')
        print('----------------\n')

        self.bot = bot
        self.servers = Servers()
        self.server_list = self.servers.get()
        self.messages = []
        self.message_error_count = self.current_display_server = 0

    def start(self):
        self.print_to_console(f'Starting DiscordGSM v{VERSION}...')
        self.query_servers.start()

    def cancel(self):
        self.query_servers.cancel()
        self.print_servers.cancel()
        self.presense_load.cancel()

    async def on_ready(self):
        # set username and avatar
        icon_file_name = 'images/discordgsm' + ('DGSM_TOKEN' in os.environ
                                                and '-heroku' or '') + '.png'
        with open(icon_file_name, 'rb') as file:
            try:
                await bot.user.edit(username='******', avatar=file.read())
            except:
                pass

        # print info to console
        print('\n----------------')
        print(f'Logged in as:\t{bot.user.name}')
        print(f'Robot ID:\t{bot.user.id}')
        app_info = await bot.application_info()
        print(f'Owner ID:\t{app_info.owner.id} ({app_info.owner.name})')
        print('----------------\n')

        self.print_presense_hint()
        self.presense_load.start()

        await self.set_channels_permissions()
        self.print_to_console(
            f'Query server and send discord embed every {REFRESH_RATE} seconds...'
        )
        await self.refresh_discord_embed()
        self.print_servers.start()

    # query the servers
    @tasks.loop(seconds=REFRESH_RATE)
    async def query_servers(self):
        server_count = self.servers.query()
        self.print_to_console(f'{server_count} servers queried')

    # pre-query servers before ready
    @query_servers.before_loop
    async def before_query_servers(self):
        self.print_to_console('Pre-Query servers...')
        server_count = self.servers.query()
        self.print_to_console(f'{server_count} servers queried')
        await self.bot.wait_until_ready()
        await self.on_ready()

    # send messages to discord
    @tasks.loop(seconds=REFRESH_RATE)
    async def print_servers(self):
        if self.message_error_count < 20:
            updated_count = 0
            for i in range(len(self.server_list)):
                try:
                    await self.messages[i].edit(
                        content=('frontMessage' in self.server_list[i] and
                                 self.server_list[i]['frontMessage'].strip())
                        and self.server_list[i]['frontMessage'] or None,
                        embed=self.get_embed(self.server_list[i]))
                    updated_count += 1
                except:
                    self.message_error_count += 1
                    self.print_to_console(
                        f'ERROR: message {i} fail to edit, message deleted or no permission. Server: {self.server_list[i]["addr"]}:{self.server_list[i]["port"]}'
                    )

            self.print_to_console(f'{updated_count} messages updated')
        else:
            self.message_error_count = 0
            self.print_to_console(f'Message ERROR reached, refreshing...')
            await self.refresh_discord_embed()

    # refresh discord presense
    @tasks.loop(minutes=PRESENCE_RATE)
    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}dgsm'
        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'
            else:
                activity_text = None

            self.current_display_server += 1

        if activity_text != None:
            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}')

    # set channels permissions before sending new messages
    async def set_channels_permissions(self):
        channels = [server['channel'] for server in self.server_list]
        channels = list(set(channels))  # remove duplicated channels
        for channel in channels:
            try:
                await bot.get_channel(channel).set_permissions(
                    bot.user,
                    read_messages=True,
                    send_messages=True,
                    reason='Display servers embed')
                self.print_to_console(
                    f'Channel: {channel} | Permissions: read_messages, send_messages | Permissions set successfully'
                )
            except:
                self.print_to_console(
                    f'Channel: {channel} | Permissions: read_messages, send_messages | ERROR: Permissions fail to set'
                )

    # remove old discord embed and send new discord embed
    async def refresh_discord_embed(self):
        # refresh servers.json cache
        self.servers = Servers()
        self.server_list = self.servers.get()

        # remove old discord embed
        channels = [server['channel'] for server in self.server_list]
        channels = list(set(channels))  # remove duplicated channels
        for channel in channels:
            await bot.get_channel(channel).purge(
                check=lambda m: m.author == bot.user)

        # send new discord embed
        self.messages = [
            await bot.get_channel(s['channel']).send(
                content=('frontMessage' in s and s['frontMessage'].strip())
                and s['frontMessage'] or None,
                embed=self.get_embed(s)) for s in self.server_list
        ]

    def print_to_console(self, value):
        print(datetime.now().strftime('%Y-%m-%d %H:%M:%S: ') + value)

    # 1 = display number of servers, 2 = display total players/total maxplayers, 3 = display each server one by one every 10 minutes
    def print_presense_hint(self):
        if PRESENCE_TYPE <= 1:
            hints = 'number of servers'
        elif PRESENCE_TYPE == 2:
            hints = 'total players/total maxplayers'
        elif PRESENCE_TYPE >= 3:
            hints = f'each server one by one every {PRESENCE_RATE} minutes'
        self.print_to_console(
            f'Presence update type: {PRESENCE_TYPE} | Display {hints}')

    # get game server discord embed
    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_server_list(self):
        return self.server_list
Ejemplo n.º 4
0
class DiscordGSM():
    def __init__(self, client):

        self.client = client
        self.servers = Servers()
        self.server_list = self.servers.get()
        self.message_error_count = self.current_display_server = 0

    def start(self):
        self.print_to_console(f'Starting DiscordGSM v.{VERSION}')
        self.update_messages.start()

    def cancel(self):
        self.update_messages.cancel()
        self.presence_load.cancel()

    async def on_ready(self):
        # set username and avatar | not very nice for self-hosted users.
        # icon_file_name = "images/discordgsm" + ("DGSM_TOKEN" in os.environ and "-heroku" or "") + ".png"
        # with open(icon_file_name, "rb") as file:
        #     try:
        #         await client.user.edit(username="******", avatar=file.read())
        #     except Exception as e:
        #         pass

        # print info to console
        print("\n----------------")
        print(f'Logged in as:\t{client.user.name}')
        print(f'Client ID:\t{client.user.id}')
        app_info = await client.application_info()
        print(f'Owner ID:\t{app_info.owner.id} ({app_info.owner.name})')
        print(f'Invite Link: \t{invite_link}')
        print("----------------")
        print(
            f'Querying {self.servers.get_distinct_server_count()} servers and updating {len(self.server_list)} messages every {REFRESH_RATE} minutes.'
        )
        print("----------------\n")
        self.presence_load.start()

    @tasks.loop(minutes=REFRESH_RATE)
    async def update_messages(self):
        await self.query_servers()
        updated_count = 0
        for server in self.server_list:
            if self.message_error_count > ERROR_THRESHOLD:
                self.message_error_count = 0
                self.print_to_console(
                    f'ERROR: update_messages error threshold({ERROR_THRESHOLD}) reached. Reposting messages.'
                )
                await self.repost_messages()
                break
            try:
                message = await self.try_get_message_to_update(server)
                if not message:
                    self.message_error_count += 1
                    self.print_to_console(
                        f'\n {self.message_error_count} error(s) in update_messages().'
                    )
                    continue
                await message.edit(embed=self.get_embed(server))
                updated_count += 1
            except Exception as e:
                self.message_error_count += 1
                self.print_to_console(
                    f'ERROR: Failed to edit message for server: {self.get_server_info(server)}. \n {self.message_error_count} error(s) in update_messages(). Missing permissions?\n{e}'
                )
            finally:
                await asyncio.sleep(SEND_DELAY)
        self.print_to_console(f'{updated_count} messages updated.')

    # pre-query servers before ready
    @update_messages.before_loop
    async def before_update_messages(self):
        await self.query_servers()
        await client.wait_until_ready()
        await self.on_ready()

    # remove old discord embed and send new discord embed
    async def repost_messages(self):
        self.servers = Servers()
        self.server_list = self.servers.get()
        repost_count = 0
        # remove old discord embed
        channels = [server["channel"] for server in self.server_list]
        channels = list(set(channels))  # remove duplicated channels
        for channel in channels:
            try:
                await client.get_channel(channel).purge(
                    check=lambda m: m.author == client.user)
            except Exception as e:
                self.print_to_console(
                    f'ERROR: Unable to delete bot messages.\n{e}')
            finally:
                await asyncio.sleep(SEND_DELAY)

        # send new discord embed
        for server in self.server_list:
            try:
                message = await client.get_channel(
                    server["channel"]).send(embed=self.get_embed(server))
                server["message_id"] = message.id
                repost_count += 1
            except Exception as e:
                self.message_error_count += 1
                self.print_to_console(
                    f'ERROR: Failed to send message for server: {self.get_server_info(server)}. Missing permissions ?\n{e}'
                )
            finally:
                self.servers.update_server_file(self.server_list)
                await asyncio.sleep(SEND_DELAY)
        self.print_to_console(f'{repost_count} messages reposted.')

    # 1 = display number of servers, 2 = display total players/total maxplayers, 3 = display each server one by one every 10 minutes
    def print_presense_hint(self):
        if PRESENCE_TYPE <= 1:
            hints = "number of servers"
        elif PRESENCE_TYPE == 2:
            hints = "total players/total maxplayers"
        elif PRESENCE_TYPE >= 3:
            hints = f'each server one by one every {PRESENCE_RATE} minutes'
        self.print_to_console(
            f'Presence update type: {PRESENCE_TYPE} | Display {hints}')

    # refresh discord presence
    @tasks.loop(minutes=PRESENCE_RATE)
    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":
                    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 print_to_console(self, value):
        print(datetime.now().strftime("%Y-%m-%d %H:%M:%S: ") + value)

    async def try_get_message_to_update(self, server):
        try:
            message = await client.get_channel(
                server["channel"]).fetch_message(server["message_id"])
            if not message:
                self.print_to_console(
                    f'ERROR: Failed to fetch message for server: {self.get_server_info(server)}.'
                )
                return None
            return message
        except Exception as e:
            self.print_to_console(
                f'ERROR: Failed to fetch message for server: {self.get_server_info(server)}. \n{e}'
            )
            return None
        finally:
            await asyncio.sleep(SEND_DELAY)

    async def query_servers(self):
        try:
            self.server_list = self.servers.refresh()
            self.servers.query()
        except Exception as e:
            self.print_to_console(f'Error Querying servers: \n{e}')
        self.print_to_console(
            f'{self.servers.get_distinct_server_count()} servers queried.')

    def get_value(self, dataset, field, default=None):
        if type(dataset) != dict or field not in dataset or dataset[
                field] is None or dataset[field] == "":
            return default
        return dataset[field]

    def get_server_info(self, server):
        return self.get_value(server, "comment",
                              f'{server["address"]}:{server["port"]}')

    def get_server_list(self):
        return self.server_list

    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 determineColor(self, server, data, cache_status):
        players = self.get_value(data, "players", "?")
        maxplayers = self.get_value(data, "maxplayers") or self.get_value(
            server, "maxplayers") or "?"

        if cache_status == "Online" and players != "?" and maxplayers != "??":
            if players >= maxplayers:
                color = discord.Color.from_rgb(240, 71, 71)  # red
            elif players >= maxplayers / 2:
                color = discord.Color.from_rgb(250, 166, 26)  # yellow
            else:
                color = discord.Color.from_rgb(67, 181, 129)  # green
        else:
            color = discord.Color.from_rgb(0, 0, 0)  # black

        # color is defined
        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:
            pass

        return color

    def determinePlayerString(self, server, data, cache_status):

        players = self.get_value(data, "players", "?")
        maxplayers = self.get_value(data, "maxplayers") or self.get_value(
            server, "maxplayers") or "?"

        bots = self.get_value(data, "bots")

        if cache_status == "Offline":
            players = 0
            bots = None
        if data == False:
            players = "?"
            bots = None

        return f'{players}({bots})/{maxplayers}' if bots is not None and bots > 0 else f'{players}/{maxplayers}'
Ejemplo n.º 5
0
        os.remove(os.path.join('cache', file))

# get settings
print('Setting up...')
settings = Settings.get()

# bot token
TOKEN = os.getenv('DGSM_TOKEN', settings['token'])

# set up bot
bot = commands.Bot(command_prefix=settings['prefix'])

# query servers and save cache
print('Pre-Query servers...')
game_servers = Servers()
game_servers.query()

# get servers
servers = game_servers.load()

# discord messages
messages = []

# boolean is currently refreshing
is_refresh = False

# bot ready action
@bot.event
async def on_ready():
    # set username and avatar
    with open('images/bitfor.jpg', 'rb') as file: