Merge branch 'feature/reconnect-failsafe'

master
Tristan Gosselin-Hane 6 years ago
commit 7fc5d487c8
No known key found for this signature in database
GPG Key ID: 0B7E55B60DCA15D5
  1. 1
      README.md
  2. 1
      config.example.json
  3. 1
      minecraft_discord_bridge/config.py
  4. 18
      minecraft_discord_bridge/minecraft_discord_bridge.py

@ -82,6 +82,7 @@ All of the configuration data is stored in a file called `config.json` that must
|MAIN.DISCORD_APP_TOKEN |"" |The discord bot token the birdge will use to log into discord |MAIN.DISCORD_APP_TOKEN |"" |The discord bot token the birdge will use to log into discord
|MAIN.LOG_LEVEL |"INFO" |Set the log level, can be `INFO` or `DEBUG` |MAIN.LOG_LEVEL |"INFO" |Set the log level, can be `INFO` or `DEBUG`
|MAIN.MESSAGE_DELAY |1.5 |Set the delay between messages sent from discord to minecraft |MAIN.MESSAGE_DELAY |1.5 |Set the delay between messages sent from discord to minecraft
|MAIN.FAILSAFE_RETRIES |3 |The amount of times to try reconnecting to an online server before giving up and exiting.
|MAIN.ADMINS |\[283983554051047425\] |Array of discord user ids that have administrative access to the bot |MAIN.ADMINS |\[283983554051047425\] |Array of discord user ids that have administrative access to the bot
|AUTH_SERVER.BIND.IP |"" |The IPv4 address which the authentication server will bind to (set to blank for 0.0.0.0) |AUTH_SERVER.BIND.IP |"" |The IPv4 address which the authentication server will bind to (set to blank for 0.0.0.0)
|AUTH_SERVER.PORT |9822 |The port which the authentication server will bind to |AUTH_SERVER.PORT |9822 |The port which the authentication server will bind to

@ -8,6 +8,7 @@
"DISCORD_APP_TOKEN": "", "DISCORD_APP_TOKEN": "",
"LOG_LEVEL": "INFO", "LOG_LEVEL": "INFO",
"MESSAGE_DELAY": 1.5, "MESSAGE_DELAY": 1.5,
"FAILSAFE_RETRIES": 3,
"ADMINS": [ "ADMINS": [
283983554051047425 283983554051047425
] ]

@ -36,6 +36,7 @@ class Configuration(object):
self.discord_token = self._config["MAIN"]["DISCORD_APP_TOKEN"] self.discord_token = self._config["MAIN"]["DISCORD_APP_TOKEN"]
self.logging_level = self._config["MAIN"]["LOG_LEVEL"] self.logging_level = self._config["MAIN"]["LOG_LEVEL"]
self.message_delay = self._config["MAIN"]["MESSAGE_DELAY"] self.message_delay = self._config["MAIN"]["MESSAGE_DELAY"]
self.failsafe_retries = self._config["MAIN"]["FAILSAFE_RETRIES"]
self.admin_users = self._config["MAIN"]["ADMINS"] self.admin_users = self._config["MAIN"]["ADMINS"]
self.auth_ip = self._config["AUTH_SERVER"]["BIND_IP"] self.auth_ip = self._config["AUTH_SERVER"]["BIND_IP"]
self.auth_port = self._config["AUTH_SERVER"]["PORT"] self.auth_port = self._config["AUTH_SERVER"]["PORT"]

@ -43,6 +43,8 @@ from mcstatus import MinecraftServer
from bidict import bidict from bidict import bidict
from requests_futures.sessions import FuturesSession from requests_futures.sessions import FuturesSession
import _thread
import minecraft_discord_bridge import minecraft_discord_bridge
from .database_session import DatabaseSession from .database_session import DatabaseSession
from .elasticsearch_logger import ElasticsearchLogger, ConnectionReason from .elasticsearch_logger import ElasticsearchLogger, ConnectionReason
@ -66,6 +68,7 @@ class MinecraftDiscordBridge():
# Initialize the discord part # Initialize the discord part
self.discord_bot = discord.Client() self.discord_bot = discord.Client()
self.config = Configuration("config.json") self.config = Configuration("config.json")
self.connection_retries = 0
self.auth_token = None self.auth_token = None
self.connection = None self.connection = None
self.setup_logging(self.config.logging_level) self.setup_logging(self.config.logging_level)
@ -494,10 +497,11 @@ class MinecraftDiscordBridge():
handle_exception=self.minecraft_handle_exception) handle_exception=self.minecraft_handle_exception)
self.register_handlers(self.connection) self.register_handlers(self.connection)
self.connection_retries += 1
self.connection.connect() self.connection.connect()
try: try:
self.aioloop.run_until_complete(self.discord_bot.start(self.config.discord_token)) self.aioloop.run_until_complete(self.discord_bot.start(self.config.discord_token))
except KeyboardInterrupt: except (KeyboardInterrupt, SystemExit):
# log out of discord # log out of discord
self.aioloop.run_until_complete(self.discord_bot.logout()) self.aioloop.run_until_complete(self.discord_bot.logout())
# log out of minecraft # log out of minecraft
@ -638,6 +642,14 @@ class MinecraftDiscordBridge():
self.logger.info('Disconnected.') self.logger.info('Disconnected.')
if json_data: if json_data:
self.logger.info("Disconnect json data: %s", json_data) self.logger.info("Disconnect json data: %s", json_data)
if self.connection_retries >= self.config.failsafe_retries:
self.logger.info("Failed to join the server %s times in a row. Exiting.", self.connection_retries)
self.logger.info("Use a process supervisor if you wish to automatically restart the bridge.")
# This is possibly a huge hack... Since we cannot reliably raise exceptions on this thread
# for them to be caught on the main thread, we call interrupt_main to raise a KeyboardInterrupt
# on main and tell it to shut the bridge down.
_thread.interrupt_main()
return
self.previous_player_list = self.player_list.copy() self.previous_player_list = self.player_list.copy()
self.accept_join_events = False self.accept_join_events = False
self.player_list = bidict() self.player_list = bidict()
@ -649,6 +661,7 @@ class MinecraftDiscordBridge():
self.logger.info('Not reconnecting to server because it appears to be offline.') self.logger.info('Not reconnecting to server because it appears to be offline.')
time.sleep(15) time.sleep(15)
self.logger.info('Reconnecting.') self.logger.info('Reconnecting.')
self.connection_retries += 1
self.connection.connect() self.connection.connect()
def handle_disconnect_packet(self, disconnect_packet): def handle_disconnect_packet(self, disconnect_packet):
@ -764,6 +777,7 @@ class MinecraftDiscordBridge():
def handle_join_game(self, join_game_packet): def handle_join_game(self, join_game_packet):
self.logger.info('Connected and joined game as entity id %d', join_game_packet.entity_id) self.logger.info('Connected and joined game as entity id %d', join_game_packet.entity_id)
self.player_list = bidict() self.player_list = bidict()
self.connection_retries = 0
def handle_chat(self, chat_packet): def handle_chat(self, chat_packet):
json_data = json.loads(chat_packet.json_data) json_data = json.loads(chat_packet.json_data)
@ -822,7 +836,7 @@ class MinecraftDiscordBridge():
def handle_sigterm(*args, **kwargs): def handle_sigterm(*args, **kwargs):
raise KeyboardInterrupt() raise KeyboardInterrupt
def main(): def main():

Loading…
Cancel
Save