This repository has been archived by the owner on Apr 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
status-bot.py
executable file
·110 lines (100 loc) · 4.52 KB
/
status-bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env python
import asyncio
import discord
import os
from dotenv import load_dotenv
from mcstatus import MinecraftServer
from socket import gaierror, timeout
load_dotenv()
CHECK_INTERVAL = int(os.getenv("CHECK_INTERVAL"))
DISCORD_CHANNEL_ID = int(os.getenv("DISCORD_CHANNEL_ID"))
DISCORD_SERVER_ID = int(os.getenv("DISCORD_SERVER_ID"))
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
MINECRAFT_SERVERS = [server.strip() for server in os.getenv("MINECRAFT_SERVERS").split(',')]
client = discord.Client(activity=discord.Game(name="Minecraft"))
status_message = {}
@client.event
async def on_ready():
guild = discord.utils.get(client.guilds, id=DISCORD_SERVER_ID)
channel = client.get_channel(DISCORD_CHANNEL_ID)
print(
f"{client.user} is connected to the following server:\n"
f"'{guild.name}' (id: {guild.id})\n"
f"Posting messages to channel '{channel.name}'"
)
# Delete all messages of the bot from the channel:
async for message in channel.history():
if message.author == client.user:
await message.delete()
# Main loop for updating the status:
while True:
for server_address in MINECRAFT_SERVERS:
server = MinecraftServer.lookup(server_address)
# favicon = None
try:
server.status(retries=1)
skip_check = False
server.query(retries=1)
use_query = True
except timeout:
use_query = False
except (ConnectionRefusedError, gaierror):
skip_check = True
if skip_check:
num_players = 0
max_players = 0
player_names = ""
# motd = "N/A"
version = "N/A"
ping = "N/A"
online_color = discord.Colour.red()
online_status = "Offline ⭕"
else:
server_status = server.status()
if use_query:
server_query = server.query()
# :TODO: Convert to image and set as thumbnail.
# favicon = server_status.favicon
num_players = server_query.players.online
max_players = server_query.players.max
player_names_list = server_query.players.names
player_names_list.sort()
player_names = str("\n").join(player_names_list)
# :TODO: Handle all crazy types of MOTD.
# motd = server_query.motd
version = server_query.software.version
else:
num_players = server_status.players.online
max_players = server_status.players.max
player_names = ""
# :TODO: Handle all crazy types of MOTD.
# motd = server_status.description["text"]
version = server_status.version.name
try:
ping = f"{int(server.ping())} ms"
except IOError:
ping = "N/A"
online_color = discord.Colour.green()
online_status = "Online ✅"
embed = discord.Embed()
embed.colour = online_color
embed.description = f"**Status:** {online_status}\n\n**Version:** {version}\n**Ping:** {ping}\n**Players connected:** {num_players}/{max_players}\n\n{player_names}"
# Max length for descriptions is 2048
if len(embed.description) > 2048:
# Remove player names from the list until we're under the limit (and add "..." at the bottom):
while len(embed.description) > 2043:
player_names_list = player_names.split("\n")
player_names_list.sort()
player_names_list.pop()
player_names = player_names = str("\n").join(player_names_list)
embed.description = f"**Status:** {online_status}\n\n**Version:** {version}\n**Ping:** {ping}\n**Players connected:** {num_players}/{max_players}\n```{player_names}\n...```"
embed.set_author(name=server_address)
try:
await status_message[server_address].edit(embed=embed)
except (KeyError, discord.NotFound):
status_message[server_address] = await channel.send(embed=embed)
await asyncio.sleep(CHECK_INTERVAL)
@client.event
async def on_disconnect():
print("Disconnected...")
client.run(DISCORD_TOKEN, reconnect=True)