Example #1
0
 def __init__(self,
              bot: telegram.Bot,
              alerts_chat_id: int = config.DEFAULT_CAPTCHA_ALERTS_CHAT_ID):
     self._minecraft = Minecraft()
     self._bot = bot
     self._alerts_chat_id = alerts_chat_id
     self._captcha_sample = None
Example #2
0
class MinecraftServerReconnector(metaclass=Singleton):
    """Monitors minecraft for disconnections and crashes."""

    MAX_RECONNECT_TRIES = 5

    def __init__(self):
        self._minecraft = Minecraft()
        self._crash_event_handler = CrashDirEventHandler()
        self._init_crash_dir_observer()
        self._reconnect_tries = 0

    def keep_connected(self):
        logging.info("Starting minecraft server reconnector.")
        self._init_observer_if_stopped()
        self._crash_dir_observer.start()
        self._detect_and_handle_disconnections()

    def stop(self):
        logging.info("Stopping minecraft server reconnector.")
        self._crash_dir_observer.stop()

    def is_up(self):
        return self._crash_dir_observer.is_alive()

    def _init_observer_if_stopped(self):
        if not self.is_up():
            # Observer start method can only be invoked once per instance.
            self._init_crash_dir_observer()

    def _init_crash_dir_observer(self):
        self._crash_dir_observer = Observer()
        self._crash_dir_observer.schedule(self._crash_event_handler,
                                          config.MINECRAFT_CRASH_DIR)

    @threaded
    def _detect_and_handle_disconnections(self):
        with open(config.MINECRAFT_LOG_FILE) as log_file:
            for log_line in tailer.follow(log_file, LOG_LINE_READ_DELAY):
                if not self.is_up():
                    break
                self._process_log_line(log_line)

    def _process_log_line(self, line):
        if re.match(DISCONNECTION_LOG, line):
            logging.warning("Disconnection from hypixel detected.")
            self._handle_disconnection()
        elif re.match(JOIN_SERVER_LOG, line):
            logging.info("Successfully reconnected.")
            self._reconnect_tries = 0

    def _handle_disconnection(self):
        if self._reconnect_tries < self.MAX_RECONNECT_TRIES:
            self._minecraft.connect()
            self._reconnect_tries += 1
        else:
            logging.warning("Max retries exceeded, relaunching minecraft.")
            self._minecraft.relaunch()
            self._reconnect_tries = 0
Example #3
0
class CrashDirEventHandler(FileSystemEventHandler):
    """Handles file system events in crash reports directory."""
    def __init__(self):
        super().__init__()
        self._minecraft = Minecraft()

    def on_created(self, event):
        """Relaunch minecraft when a new crash report is detected."""
        logging.warning("Crash report detected.")
        self._minecraft.relaunch()
Example #4
0
class UpdateCobbleMiner(UpdateCommand):
    """Update minecraft macro scripts."""
    SERVER_LOAD_TIME_SECS = 5

    def __init__(self):
        super().__init__('CobbleMiner', config.COBBLEMINER_MACROS_DIR)
        self._minecraft = Minecraft()

    @auth
    def run(self, update, context):
        try:
            self._reply(update, context, ReplyMsg.UPDATE_COBBLEMINER.value)
            self._repo_installer.install_latest_files()
            self._apply_macro_changes()
            self._reply(update, context, ReplyMsg.MACROS_INSTALLED.value)
        except RepoInstallError:
            self._reply(update, context, ReplyMsg.UPDATE_FAILED.value)

    def _apply_macro_changes(self):
        self._minecraft.reconnect()
        time.sleep(self.SERVER_LOAD_TIME_SECS)
Example #5
0
class CaptchaDetector(metaclass=Singleton):
    def __init__(self,
                 bot: telegram.Bot,
                 alerts_chat_id: int = config.DEFAULT_CAPTCHA_ALERTS_CHAT_ID):
        self._minecraft = Minecraft()
        self._bot = bot
        self._alerts_chat_id = alerts_chat_id
        self._captcha_sample = None

    def set_alerts_target_chat(self, chat_id):
        self._alerts_chat_id = chat_id

    @threaded
    def run_forever(self):
        logging.info("Starting captcha detector.")
        with open(config.CAPTCHA_ALERTS_FILE) as captcha_file:
            for _ in tailer.follow(captcha_file, LOG_LINE_READ_DELAY):
                self._save_captcha_sample()
                self._send_alert()

    def _save_captcha_sample(self):
        self._captcha_sample = self._build_captcha_save_path()
        self._minecraft.save_live_image(self._captcha_sample)

    @staticmethod
    def _build_captcha_save_path():
        if not os.path.exists(config.CAPTCHA_SAMPLES_DIR):
            os.makedirs(config.CAPTCHA_SAMPLES_DIR)

        curr_dir = pathlib.Path().absolute()
        curr_time = datetime.now().strftime("%d-%m-%Y %H;%M;%S")
        return f"{curr_dir}\\{config.CAPTCHA_SAMPLES_DIR}\\{curr_time}.png"

    def _send_alert(self):
        logging.warning("Captcha detected! Sending alert via telegram.")
        with open(self._captcha_sample, "rb") as img:
            self._bot.send_photo(chat_id=self._alerts_chat_id, photo=img)
            self._bot.send_message(chat_id=self._alerts_chat_id,
                                   text=commands.ReplyMsg.CAPTCHA_ALERT.value)
Example #6
0
 def __init__(self):
     self._minecraft = Minecraft()
     self._crash_event_handler = CrashDirEventHandler()
     self._init_crash_dir_observer()
     self._reconnect_tries = 0
Example #7
0
 def __init__(self):
     super().__init__()
     self._minecraft = Minecraft()
Example #8
0
 def __init__(self):
     super().__init__('CobbleMiner', config.COBBLEMINER_MACROS_DIR)
     self._minecraft = Minecraft()
Example #9
0
 def __init__(self):
     self._minecraft = Minecraft()