Esempio n. 1
0
def start_server():
    ''' Main entry point for the application '''
    if options.debug:
        logging.warn(
            "%sDebug mode is enabled; DO NOT USE THIS IN PRODUCTION%s" %
            (bold + R, W))
    if options.autostart_game:
        logging.info("The game is about to begin, good hunting!")
        app.settings['history_callback'].start()
        if options.use_bots:
            app.settings['score_bots_callback'].start()
    # Setup server object
    if options.ssl:
        server = HTTPServer(app,
                            ssl_options={
                                "certfile": options.certfile,
                                "keyfile": options.keyfile,
                            },
                            xheaders=options.x_headers)
    else:
        server = HTTPServer(app, xheaders=options.x_headers)
    sockets = netutil.bind_sockets(options.listen_port,
                                   options.listen_interface)
    server.add_sockets(sockets)
    Scoreboard.now(app)
    try:
        io_loop.start()
    except KeyboardInterrupt:
        sys.stdout.write('\r' + WARN + 'Shutdown Everything!\n')
    except:
        logging.exception("Main i/o loop threw exception")
    finally:
        io_loop.stop()
        _exit(0)
Esempio n. 2
0
def start_server():
    ''' Main entry point for the application '''
    if options.debug:
        logging.warn("%sDebug mode is enabled; DO NOT USE THIS IN PRODUCTION%s" % (
            bold + R, W
        ))
    if options.autostart_game:
        logging.info("The game is about to begin, good hunting!")
        app.settings['history_callback'].start()
        if options.use_bots:
            app.settings['score_bots_callback'].start()
    # Setup server object
    if options.ssl:
        server = HTTPServer(app,
                            ssl_options={
                                "certfile": options.certfile,
                                "keyfile": options.keyfile,
                            },
                            xheaders=options.x_headers
                            )
    else:
        server = HTTPServer(app, xheaders=options.x_headers)
    sockets = netutil.bind_sockets(options.listen_port, options.listen_interface)
    server.add_sockets(sockets)
    Scoreboard.now(app)
    try:
        io_loop.start()
    except KeyboardInterrupt:
        sys.stdout.write('\r' + WARN + 'Shutdown Everything!\n')
    except:
        logging.exception("Main i/o loop threw exception")
    finally:
        io_loop.stop()
        _exit(0)
Esempio n. 3
0
def start_server():
    """ Main entry point for the application """
    if options.debug:
        logging.warn(
            "%sDebug mode is enabled; DO NOT USE THIS IN PRODUCTION%s" %
            (bold + R, W))
    locale.set_default_locale("en_US")
    locale.load_translations("locale")
    if options.autostart_game:
        logging.info("The game is about to begin, good hunting!")
        app.settings["history_callback"].start()
        if options.use_bots:
            app.settings["score_bots_callback"].start()
    # Setup server object
    if options.ssl:
        server = HTTPServer(
            app,
            ssl_options={
                "certfile": options.certfile,
                "keyfile": options.keyfile
            },
            xheaders=options.x_headers,
        )
    else:
        server = HTTPServer(app, xheaders=options.x_headers)
    try:
        sockets = netutil.bind_sockets(options.listen_port,
                                       options.listen_interface)
    except (OSError, IOError) as err:
        if err.errno == 13:
            pypath = sys.executable
            if os_path.islink(pypath):
                pypath = os_path.realpath(pypath)
            logging.error("Problem binding to port %s",
                          str(options.listen_port))
            logging.error(
                "Possible Fix: sudo setcap CAP_NET_BIND_SERVICE=+eip %s",
                pypath)
            sys.exit()
    server.add_sockets(sockets)
    try:
        Scoreboard.now(app)
    except OperationalError as err:
        if "Table definition has changed" in str(err):
            logging.info(
                "Table definitions have changed -restarting RootTheBox.")
            return "restart"
        else:
            logging.error("There was a problem starting RootTheBox. Error: " +
                          str(err))
    try:
        io_loop.start()
    except KeyboardInterrupt:
        sys.stdout.write("\r" + WARN + "Shutdown Everything!\n")
    except:
        logging.exception("Main i/o loop threw exception")
    finally:
        io_loop.stop()
        _exit(0)
 def on_message(self, message):
     ''' We ignore messages if there are more than 1 every 3 seconds '''
     if self.application.settings['freeze_scoreboard']:
         self.write_message("pause")
     elif datetime.now() - self.last_message > timedelta(seconds=3):
         self.last_message = datetime.now()
         self.write_message(Scoreboard.now())
 def open(self):
     ''' When we receive a new websocket connect '''
     self.connections.add(self)
     if self.application.settings['freeze_scoreboard']:
         self.write_message("pause")
     else:
         self.write_message(Scoreboard.now())
Esempio n. 6
0
 def open(self):
     """ When we receive a new websocket connect """
     self.connections.add(self)
     if self.application.settings["freeze_scoreboard"]:
         self.write_message("pause")
     else:
         self.write_message(Scoreboard.now(self))
Esempio n. 7
0
 def on_message(self, message):
     """ We ignore messages if there are more than 1 every 3 seconds """
     if self.application.settings["freeze_scoreboard"]:
         self.write_message("pause")
     elif datetime.now() - self.last_message > timedelta(seconds=3):
         self.last_message = datetime.now()
         Scoreboard.update_gamestate(self)
         self.write_message(Scoreboard.now(self))
Esempio n. 8
0
class EventManager(object):
    '''
    All event callbacks go here!
    This class holds refs to all open web sockets
    '''
    def __init__(self):
        self.notify_connections = {}
        self.scoreboard_connections = []
        self.history_connections = []
        self.scoreboard = Scoreboard()

    @property
    def users_online(self):
        ''' Number of currently open notify sockets '''
        sumation = 0
        for team_id in self.notify_connections:
            sumation += len(self.notify_connections[team_id])
        return sumation

    def is_online(self, user):
        ''' 
        Returns bool if the given user has an open notify socket
        '''
        if user.team.id in self.notify_connections:
            if user.id in self.notify_connections[user.team.id]:
                return 0 < len(self.notify_connections[user.team.id][user.id])
        return False

    # [ Connection Methods ] -----------------------------------------------
    def add_connection(self, wsocket):
        ''' Add a connection '''
        if not wsocket.team_id in self.notify_connections:
            self.notify_connections[wsocket.team_id] = {}
        if wsocket.user_id in self.notify_connections[wsocket.team_id]:
            self.notify_connections[wsocket.team_id][wsocket.user_id].append(
                wsocket)
        else:
            self.notify_connections[wsocket.team_id][wsocket.user_id] = [
                wsocket
            ]

    def remove_connection(self, wsocket):
        ''' Remove connection '''
        self.notify_connections[wsocket.team_id][wsocket.user_id].remove(
            wsocket)
        if len(self.notify_connections[wsocket.team_id][wsocket.user_id]) == 0:
            del self.notify_connections[wsocket.team_id][wsocket.user_id]

    def deauth(self, user):
        if user.team.id in self.notify_connections:
            if user.id in self.notify_connections[user.team.id]:
                wsocks = self.notify_connections[user.team.id][user.id]
                for wsock in wsocks:
                    wsock.write_message(
                        {'warn': "You have been deauthenticated"})
                    wsock.close()

    # [ Push Updates ] -----------------------------------------------------
    def refresh_scoreboard(self):
        ''' Push to everyone '''
        update = self.scoreboard.now()
        for wsocket in self.scoreboard_connections:
            wsocket.write_message(update)

    def push_history(self, snapshot):
        ''' Push latest snapshot to everyone '''
        for wsocket in self.history_connections:
            wsocket.write_message({'update': snapshot})

    def push_broadcast_notification(self, event_uuid):
        ''' Push to everyone '''
        json = Notification.by_event_uuid(event_uuid).to_json()
        for team_id in self.notify_connections:
            for user_id in self.notify_connections[team_id]:
                for wsocket in self.notify_connections[team_id][user_id]:
                    wsocket.write_message(json)
                    # Only mark delivered for non-public users
                    if wsocket.user_id != '$public_user':
                        Notification.delivered(user_id, event_uuid)

    def push_team_notification(self, event_uuid, team_id):
        ''' Push to one team '''
        if team_id in self.notify_connections:
            json = Notification.by_event_uuid(event_uuid).to_json()
            for user_id in self.notify_connections[team_id]:
                for wsocket in self.notify_connections[team_id][user_id]:
                    wsocket.write_message(json)
                    Notification.delivered(wsocket.user_id, event_uuid)

    def push_user_notification(self, event_uuid, team_id, user_id):
        ''' Push to one user '''
        if team_id in self.notify_connections and user_id in self.notify_connections[
                team_id]:
            json = Notification.by_event_uuid(event_uuid).to_json()
            for wsocket in self.notify_connections[team_id][user_id]:
                wsocket.write_message(json)
                Notification.delivered(wsocket.user_id, event_uuid)

    # [ Broadcast Events ] -------------------------------------------------
    def create_flag_capture_event(self, user, flag):
        ''' Callback for when a flag is captured '''
        self.refresh_scoreboard()
        evt_id = Notifier.broadcast_success(
            "Flag Capture", "%s has captured '%s'." % (
                user.team.name,
                flag.name,
            ))
        return (self.push_broadcast_notification, {'event_uuid': evt_id})

    def create_unlocked_level_event(self, user, level):
        ''' Callback for when a team unlocks a new level '''
        self.refresh_scoreboard()
        message = "%s unlocked level #%d." % (
            user.team.name,
            level.number,
        )
        evt_id = Notifier.broadcast_success("Level Unlocked", message)
        return (self.push_broadcast_notification, {'event_uuid': evt_id})

    def create_purchased_item_event(self, user, item):
        ''' Callback when a team purchases an item '''
        self.refresh_scoreboard()
        message = "%s purchased %s from the black market." % (
            user.handle,
            item.name,
        )
        evt_id = Notifier.team_success(user.team, "Upgrade Purchased", message)
        self.push_broadcast_notification(evt_id)
        message2 = "%s unlocked %s." % (
            user.team.name,
            item.name,
        )
        evt_id2 = Notifier.broadcast_warning("Team Upgrade", message2)
        return (self.push_broadcast_notification, {'event_uuid': evt_id2})

    def create_swat_player_event(self, user, target):
        message("%s called the SWAT team on %s." % (
            user.handle,
            target.handle,
        ))
        evt_id = Notifier.broadcast_warning("Player Arrested!", message)
        return (self.push_broadcast_notification, {'event_uuid': evt_id})

    # [ Team Events ] ------------------------------------------------------
    def create_joined_team_event(self, user):
        ''' Callback when a user joins a team'''
        message = "%s has joined your team." % user.handle
        evt_id = Notifier.team_success(user.team, "New Team Member", message)
        return (self.push_team_notification, {
            'event_uuid': evt_id,
            'team_id': user.team.id
        })

    def create_team_file_share_event(self, user, file_upload):
        ''' Callback when a team file share is created '''
        message = "%s has shared a file called '%s'" % (
            user.handle,
            file_upload.file_name,
        )
        evt_id = Notifier.team_success(user.team, "File Share", message)
        return (self.push_team_notification, {
            'event_uuid': evt_id,
            'team_id': user.team.id
        })

    def create_paste_bin_event(self, user, paste):
        ''' Callback when a pastebin is created '''
        message = "%s posted to the team paste-bin" % user.handle
        evt_id = Notifier.team_success(user.team, "Text Share", message)
        return (self.push_team_notification, {
            'event_uuid': evt_id,
            'team_id': user.team.id
        })

    # [ Misc Events ] ------------------------------------------------------
    def create_cracked_password_events(self, cracker, victim, password, value):
        user_msg = "Your password '%s' was cracked by %s." % (
            password,
            cracker.handle,
        )
        evt_id = Notifier.user_warning(victim, "Security Breach", user_msg)
        event1 = (self.push_user_notification, {
            'event_uuid': evt_id,
            'team_id': victim.team.id,
            'user_id': victim.id
        })
        message = "%s hacked %s's bank account and stole $%d" % (
            cracker.handle,
            victim.team.name,
            value,
        )
        evt_id = Notifier.broadcast_custom("Password Cracked", message,
                                           cracker.avatar)
        event2 = (self.push_broadcast_notification, {'event_uuid': evt_id})
        return event1, event2
Esempio n. 9
0
class EventManager(object):
    '''
    All event callbacks go here!
    This class holds refs to all open web sockets
    '''

    def __init__(self):
        self.notify_connections = {}
        self.scoreboard_connections = []
        self.history_connections = []
        self.scoreboard = Scoreboard()

    @property
    def users_online(self):
        ''' Number of currently open notify sockets '''
        sumation = 0
        for team_id in self.notify_connections:
            sumation += len(self.notify_connections[team_id])
        return sumation

    def is_online(self, user):
        ''' 
        Returns bool if the given user has an open notify socket
        '''
        if user.team.id in self.notify_connections:
            if user.id in self.notify_connections[user.team.id]:
                return 0 < len(self.notify_connections[user.team.id][user.id])
        return False

    # [ Connection Methods ] -----------------------------------------------
    def add_connection(self, wsocket):
        ''' Add a connection '''
        if not wsocket.team_id in self.notify_connections:
            self.notify_connections[wsocket.team_id] = {}
        if wsocket.user_id in self.notify_connections[wsocket.team_id]:
            self.notify_connections[wsocket.team_id][wsocket.user_id].append(wsocket)
        else:
            self.notify_connections[wsocket.team_id][wsocket.user_id] = [wsocket]

    def remove_connection(self, wsocket):
        ''' Remove connection '''
        self.notify_connections[wsocket.team_id][wsocket.user_id].remove(wsocket)
        if len(self.notify_connections[wsocket.team_id][wsocket.user_id]) == 0:
            del self.notify_connections[wsocket.team_id][wsocket.user_id]

    def deauth(self, user):
        if user.team.id in self.notify_connections:
            if user.id in self.notify_connections[user.team.id]:
                wsocks = self.notify_connections[user.team.id][user.id]
                for wsock in wsocks:
                    wsock.write_message({
                        'warn': "You have been deauthenticated"
                    })
                    wsock.close()

    # [ Push Updates ] -----------------------------------------------------
    def refresh_scoreboard(self):
        ''' Push to everyone '''
        update = self.scoreboard.now()
        for wsocket in self.scoreboard_connections:
            wsocket.write_message(update)

    def push_history(self, snapshot):
        ''' Push latest snapshot to everyone '''
        for wsocket in self.history_connections:
            wsocket.write_message({'update': snapshot})

    def push_broadcast_notification(self, event_uuid):
        ''' Push to everyone '''
        json = Notification.by_event_uuid(event_uuid).to_json()
        for team_id in self.notify_connections:
            for user_id in self.notify_connections[team_id]:
                for wsocket in self.notify_connections[team_id][user_id]:
                    wsocket.write_message(json)
                    # Only mark delivered for non-public users
                    if wsocket.user_id != '$public_user':
                        Notification.delivered(user_id, event_uuid)

    def push_team_notification(self, event_uuid, team_id):
        ''' Push to one team '''
        if team_id in self.notify_connections:
            json = Notification.by_event_uuid(event_uuid).to_json()
            for user_id in self.notify_connections[team_id]:
                for wsocket in self.notify_connections[team_id][user_id]:
                    wsocket.write_message(json)
                    Notification.delivered(wsocket.user_id, event_uuid)

    def push_user_notification(self, event_uuid, team_id, user_id):
        ''' Push to one user '''
        if team_id in self.notify_connections and user_id in self.notify_connections[team_id]:
            json = Notification.by_event_uuid(event_uuid).to_json()
            for wsocket in self.notify_connections[team_id][user_id]:
                wsocket.write_message(json)
                Notification.delivered(wsocket.user_id, event_uuid)

    # [ Broadcast Events ] -------------------------------------------------
    def flag_capture(self, user, flag):
        ''' Callback for when a flag is captured '''
        self.refresh_scoreboard()
        evt_id = Notifier.broadcast_success("Flag Capture", 
            "%s has captured '%s'." % (user.team.name, flag.name,)
        )
        self.push_broadcast_notification(evt_id)

    def unlocked_level(self, user, level):
        ''' Callback for when a team unlocks a new level '''
        self.refresh_scoreboard()
        message = "%s unlocked level #%d." % (user.team.name, level.number,)
        evt_id = Notifier.broadcast_success("Level Unlocked", message)
        self.push_broadcast_notification(evt_id)

    def purchased_item(self, user, item):
        ''' Callback when a team purchases an item '''
        self.refresh_scoreboard()
        message = "%s purchased %s from the black market." % (
            user.handle, item.name,
        )
        evt_id = Notifier.team_success(user.team, "Upgrade Purchased", message)
        self.push_broadcast_notification(evt_id)
        message2 = "%s unlocked %s." % (user.team.name, item.name,)
        evt_id2 = Notifier.broadcast_warning("Team Upgrade", message2)
        self.push_broadcast_notification(evt_id2)

    def swat_player(self, user, target):
        message("%s called the SWAT team on %s." % (user.handle, target.handle,))
        evt_id = Notifier.broadcast_warning("Player Arrested!", message)
        self.push_broadcast_notification(evt_id)

    # [ Team Events ] ------------------------------------------------------
    def joined_team(self, user):
        ''' Callback when a user joins a team'''
        message = "%s has joined your team." % user.handle
        evt_id = Notifier.team_success(user.team, "New Team Member", message)
        self.push_team_notification(evt_id, user.team.id)

    def team_file_share(self, user, file_upload):
        ''' Callback when a team file share is created '''
        message = "%s has shared a file called '%s'" % (
            user.handle, file_upload.file_name,
        )
        evt_id = Notifier.team_success(user.team, "File Share", message)
        self.push_team_notification(evt_id, user.team.id)

    def paste_bin(self, user, paste):
        ''' Callback when a pastebin is created '''
        message = "%s posted to the team paste-bin" % user.handle
        evt_id = Notifier.team_success(user.team, "Text Share", message)
        self.push_team_notification(evt_id, user.team.id)

    # [ Misc Events ] ------------------------------------------------------
    def cracked_password(self, cracker, victim, password, value):
        user_msg = "Your password '%s' was cracked by %s." % (
            password, cracker.handle,
        )
        evt_id = Notifier.user_warning(victim, "Security Breach", user_msg)
        self.push_user_notification(evt_id, victim.team.id, victim.id)
        message = "%s hacked %s's bank account and stole $%d" % (
            cracker.handle, victim.team.name, value,
        )
        evt_id = Notifier.broadcast_custom("Password Cracked",
            message, cracker.avatar
        )
        self.push_broadcast_notification(evt_id)
 def on_message(self, message):
     ''' We ignore messages if there are more than 1 every 5 seconds '''
     if self.last_message - datetime.now() > timedelta(seconds=5):
         self.last_message = datetime.now()
         self.write_message(Scoreboard.now())
 def open(self):
     ''' When we receive a new websocket connect '''
     self.connections.add(self)
     self.write_message(Scoreboard.now())
Esempio n. 12
0
class EventManager(object):
    '''
    All event callbacks go here!
    This class holds refs to all open web sockets
    '''

    def __init__(self):
        self.botnets = {}
        self.notify_connections = {}
        self.scoreboard_connections = []
        self.history_connections = []
        self.scoreboard = Scoreboard()

    # [ Connection Methods ] -----------------------------------------------

    @debug
    def add_connection(self, wsocket):
        ''' Add a connection '''
        if not wsocket.team_id in self.notify_connections:
            self.notify_connections[wsocket.team_id] = {}
        if wsocket.user_id in self.notify_connections[wsocket.team_id]:
            self.notify_connections[wsocket.team_id][wsocket.user_id].append(wsocket)
        else:
            self.notify_connections[wsocket.team_id][wsocket.user_id] = [wsocket]

    @debug
    def remove_connection(self, wsocket):
        ''' Remove connection '''
        self.notify_connections[wsocket.team_id][wsocket.user_id].remove(wsocket)
        if len(self.notify_connections[wsocket.team_id][wsocket.user_id]) == 0:
            del self.notify_connections[wsocket.team_id][wsocket.user_id]

    @debug
    def add_bot(self, bot_socket):
        ''' Add a bot to a team's botnet '''
        if not bot_socket.team.id in self.botnets:
            self.botnets[bot_socket.team.id] = {}
        if bot_socket.box.id in self.botnets[bot_socket.team.id]:
            self.botnets[bot_socket.team.id][bot_socket.box.id].close()
            del self.botnets[bot_socket.team.id][bot_socket.box.id]
        self.botnets[bot_socket.team.id][bot_socket.box.id] = bot_socket

    @debug
    def remove_bot(self, bot_socket):
        ''' Remove ref to bot connection '''
        del self.botnets[bot_socket.team.id][bot_socket.box.id]

    @debug
    def bot_count(self, team):
        ''' Get number of current bots owned by a given team '''
        if team.id in self.botnets:
            return len(self.botnets[team.id].keys())
        else:
            return 0

    @debug
    def deauth(self, user):
        pass  # Remove all socket objects for user

    # [ Push Updates ] -----------------------------------------------------

    @debug
    def refresh_scoreboard(self):
        ''' Push to everyone '''
        update = self.scoreboard.now()
        for wsocket in self.scoreboard_connections:
            wsocket.write_message(update)

    @debug
    def push_history(self, snapshot):
        ''' Push latest snapshot to everyone '''
        for wsocket in self.history_connections:
            wsocket.write_message({'update': snapshot})

    @debug
    def push_broadcast_notification(self, event_uuid):
        ''' Push to everyone '''
        json = Notification.by_event_uuid(event_uuid).to_json()
        for team_id in self.notify_connections.keys():
            for user_id in self.notify_connections[team_id].keys():
                for wsocket in self.notify_connections[team_id][user_id]:
                    wsocket.write_message(json)
                    if wsocket.user_id != '$public_user':
                        Notification.delivered(user_id, event_uuid)

    @debug
    def push_team_notification(self, event_uuid, team_id):
        ''' Push to one team '''
        json = Notification.by_event_uuid(event_uuid).to_json()
        if team_id in self.notify_connections:
            for user_id in self.notify_connections[team_id].keys():
                for wsocket in self.notify_connections[team_id][user_id]:
                    wsocket.write_message(json)
                    Notification.delivered(wsocket.user_id, event_uuid)

    @debug
    def push_user_notification(self, event_uuid, team_id, user_id):
        ''' Push to one user '''
        json = Notification.by_event_uuid(event_uuid).to_json()
        if team_id in self.notify_connections and user_id in self.notify_connections[team_id]:
            for wsocket in self.notify_connections[team_id][user_id]:
                wsocket.write_message(json)
                Notification.delivered(wsocket.user_id, event_uuid)

    # [ Broadcast Events ] -------------------------------------------------

    @debug
    def flag_capture(self, user, flag):
        ''' Callback for when a flag is captured '''
        self.refresh_scoreboard()
        evt_id = Notifier.broadcast_success("Flag Capture", 
            "%s has captured '%s'." % (user.team.name, flag.name,)
        )
        self.push_broadcast_notification(evt_id)

    @debug
    def unlocked_level(self, user, level):
        ''' Callback for when a team unlocks a new level '''
        self.refresh_scoreboard()
        message = "%s unlocked level #%d." % (user.team.name, level.number,)
        evt_id = Notifier.broadcast_success("Level Unlocked", message)
        self.push_broadcast_notification(evt_id)

    @debug
    def purchased_item(self, user, item):
        ''' Callback when a team purchases an item '''
        self.refresh_scoreboard()
        message = "%s purchased %s from the black market." % (
            user.handle, item.name,
        )
        evt_id = Notifier.team_success(user.team, "Upgrade Purchased", message)
        self.push_broadcast_notification(evt_id)
        message2 = "%s unlocked %s." % (user.team.name, item.name,)
        evt_id2 = Notifier.broadcast_warning("Team Upgrade", message2)
        self.push_broadcast_notification(evt_id2)

    @debug
    def swat_player(self, user, target):
        message("%s called the SWAT team on %s." % (user.handle, target.handle,))
        evt_id = Notifier.broadcast_warning("Player Arrested!", message)
        self.push_broadcast_notification(evt_id)

    # [ Team Events ] ------------------------------------------------------

    @debug
    def joined_team(self, user):
        ''' Callback when a user joins a team'''
        message = "%s has joined your team." % user.handle
        evt_id = Notifier.team_success(user.team, "New Team Member", message)
        self.push_team_notification(evt_id, user.team.id)

    @debug
    def team_file_share(self, user, file_upload):
        ''' Callback when a team file share is created '''
        message = "%s has shared a file called '%s'" % (
            user.handle, file_upload.file_name,
        )
        evt_id = Notifier.team_success(user.team, "File Share", message)
        self.push_team_notification(evt_id, user.team.id)

    @debug
    def paste_bin(self, user, paste):
        ''' Callback when a pastebin is created '''
        message = "%s posted to the team paste-bin" % user.handle
        evt_id = Notifier.team_success(user.team, "Text Share", message)
        self.push_team_notification(evt_id, user.team.id)

    @debug
    def new_bot(self, bot):
        message = "New bot connected to botnet from %s " % (bot.box.name,)
        evt_id = Notifier.team_success(bot.team, "Botnet", message)
        self.push_team_notification(evt_id)

    @debug
    def lost_bot(self, bot):
        message = "Lost communication with bot on %s" % (bot.box.name,)
        evt_id = Notifier.team_warning(bot.team, "Botnet", message)
        self.push_team_notification(evt_id)

    # [ Misc Events ] ------------------------------------------------------

    @debug
    def cracked_password(self, cracker, victim, password, value):
        user_msg = "Your password '%s' was cracked by %s." % (
            password, cracker.handle,
        )
        evt_id = Notifier.user_warning(victim, "Security Breach", user_msg)
        self.push_user_notification(evt_id, victim.team.id, victim.id)
        message = "%s hacked %s's bank account and stole $%d" % (
            cracker.handle, victim.team.name, value,
        )
        evt_id = Notifier.broadcast_custom("Password Cracked",
            message, cracker.avatar
        )
        self.push_broadcast_notification(evt_id)