Ejemplo n.º 1
0
    def __init__(self):
        self.notify = Notify('Sterner.log')

        #database api
        self.db_api = DBApi()

        #start network server
        self.network = SternerNetwork(self, self.notify, self.db_api)
        self.network.startServer()

        #dict to save logged in players
        # K: player_id , V: panda connection
        self.logged_in_players = {}

        self.notify.info("Sterner started.")

        #so we dont have different versions of games all at once
        self.db_api.finishAllGamesExceptVersion(COMMUNICATION_PROTOCOL_VERSION)

        #dequeue for sending msgs to network... format:(player_id, (msg))
        self.to_network = collections.deque()

        #dequeue for sending messages for engines and EngineHandlerThread, if msg[0] == STERNER_ID, than it is for handler
        self.msgs4engines = collections.deque()

        #dequeue in which EngineHandlerThread puts messages for Sterner
        self.fromHandler = collections.deque()

        self.engine_handler = EngineHandlerThread(self.fromHandler,
                                                  self.msgs4engines,
                                                  self.to_network, self.notify,
                                                  self.db_api)
        self.engine_handler.start()
Ejemplo n.º 2
0
 def __init__(self, db, notification_io, notification_config):
     """
     Constructs the taks API.
     Args:
         db (DB): Client class to communicate with DB.
         notification_io (AbstractNotificationIO): A service to notify persons.
         notification_config (dict): The configuration for mail messages.
     """
     DBApi.__init__(self, db=db, table_name=u"task")
     self._notification_io = notification_io
     self._notification_config = notification_config
     self._task_status_change_notification = db.task_status_change_notification
Ejemplo n.º 3
0
    def create(self, document, lookup=None, auto_lookup=None):
        """
        Delete item(s).
        Args:
            filters (dict): Filter to know what to delete.
            update (dict): Fields to update.
            lookup (list of dict): Lookup option (joins).
            auto_lookup (int): Let the database construct the lookups (value is the deep).
        Returns:
            (dict): The result of the deletion (with number of items deleted).
        """
        result = DBApi.create(self, document, lookup, auto_lookup)
        if self._notification_config.get(u"ACTIVE", False):
            user_email = document['user']['email']
            task_id = document[u"task"][u"id"]

            task = list(
                self._task_notification.find(
                    {u"TASK_ID": document[u"task"][u"id"]}))[0]
            task[u"TASK_LINK"] = u"{}/{}".format(
                self._notification_config[u"APP_URL"], task[u"TASK_LINK"])
            self._notification_io.notify(
                recipient=user_email,
                subject=(
                    self._notification_config[u"USER_AFFECTED"][u"SUBJECT"] %
                    task),
                message=(
                    self._notification_config[u"USER_AFFECTED"][u"MESSAGE"] %
                    task))

        return result
Ejemplo n.º 4
0
    def update_id(self, document_id, update, lookup=None, auto_lookup=None):
        """
        Delete item(s).
        Args:
            id (int): The ID of the document to update.
            update (dict): Fields to update.
            lookup (list of dict): Lookup option (joins).
            auto_lookup (int): Let the database construct the lookups (value is the deep).
        Returns:
            (dict): The result of the deletion (with number of items deleted).
        """

        old_task = self.get(document_id, lookup, auto_lookup)
        new_task = DBApi.update_id(self, document_id, update, lookup,
                                   auto_lookup)

        if self._notification_config.get(
                u"ACTIVE",
                False) and old_task[u"completed"] != new_task[u"completed"]:
            notifications = list(
                self._task_status_change_notification.find(
                    query={u"TASK_ID": document_id}))

            common_task_notification = notifications[0]

            recipients = [
                item[u"USER_EMAIL"] for item in notifications
                if item[u"USER_EMAIL"] is not None
            ]

            if common_task_notification[u"AUTHOR_EMAIL"] not in recipients:
                recipients.append(common_task_notification[u"AUTHOR_EMAIL"])

            common_task_notification[u"TASK_LINK"] = u"{}/{}".format(
                self._notification_config[u"APP_URL"],
                common_task_notification[u"TASK_LINK"])

            OPERATION = u"TASK_REOPENED" if not new_task[
                u"completed"] else u"TASK_CLOSED"

            self._notification_io.notify(
                recipient=recipients,
                subject=(self._notification_config[OPERATION][u"SUBJECT"] %
                         common_task_notification),
                message=(self._notification_config[OPERATION][u"MESSAGE"] %
                         common_task_notification))
Ejemplo n.º 5
0
    def create(self, document, lookup=None, auto_lookup=None):
        """
        Delete item(s).
        Args:
            filters (dict): Filter to know what to delete.
            update (dict): Fields to update.
            lookup (list of dict): Lookup option (joins).
            auto_lookup (int): Let the database construct the lookups (value is the deep).
        Returns:
            (dict): The result of the deletion (with number of items deleted).
        """
        result = DBApi.create(self, document, lookup, auto_lookup)

        if self._notification_config.get(u"ACTIVE", False):
            notifications = list(
                self._comment_notification.find(
                    query={u"TASK_ID": document[u"task"].get(u"id")}))

            if len(notifications) > 0:
                common_notification = notifications[0]
                common_notification[u"TASK_LINK"] = u"{}/{}".format(
                    self._notification_config[u"APP_URL"],
                    common_notification[u"TASK_LINK"])
                common_notification[u"AUTHOR_MAIL"] = document[u"author"][
                    u'email']
                common_notification[u"AUTHOR_NAME"] = document[u"author"][
                    u'name']

                recipient_emails = [
                    notif[u"USER_EMAIL"] for notif in notifications
                ] + [common_notification[u"TASK_AUTHOR_EMAIL"]]

                # If comment writer is in recipients, remove it.
                recipient_emails = [
                    email for email in recipient_emails
                    if email != common_notification[u"AUTHOR_MAIL"]
                ]

                self._notification_io.notify(
                    recipient=list(set(recipient_emails)),
                    subject=self._notification_config[u"COMMENT_ADDED"]
                    [u"SUBJECT"] % common_notification,
                    message=self._notification_config[u"COMMENT_ADDED"]
                    [u"MESSAGE"] % common_notification)

        return result
Ejemplo n.º 6
0
from dbapi import DBApi
from dbapi import Song
import os

dbapi = DBApi()

img_path = "/home/garrison/Cloud/work/chords/public/img/chords/guitar"
img_chords = list(map(lambda x: x.replace(".gif", ""), os.listdir(img_path)))

badchords = set()

songs = dbapi.session.query(Song).all()
for song in songs:
    chords = song.guitar_chords.split(";")
    for ch in chords:
        if ch not in img_chords:
            badchords.add(ch)

print(sorted(badchords))
print(len(badchords))
"""
rename IMGS:
rename 's/_0//' *
rename 's/w/#/' *

SQL QUERIES:

update songs
	set guitar_chords = REPLACE(guitar_chords, "/", "|")

update songs
Ejemplo n.º 7
0
                         }})


# Init & register User API
# Create user api object
USER_API = user_api.create_user_api(
    db_url=USER_API_CONFIG.get(u"db_url"),
    jwt_secret=USER_API_CONFIG.get(u"jwt_secret"),
    jwt_lifetime=USER_API_CONFIG.get(u"jwt_lifetime"),
    user_created_callback=on_user_created,
    user_updated_callback=on_user_updated)

FLASK_USER_API = USER_API.get_flask_user_api()

DB_API_CONFIG = {
    u"projects": DBApi(DB, u"project"),
    u"clients": DBApi(DB, u"client"),
    u"hours": DBApi(DB, u"hour"),
    u"project_assignements": DBApi(DB, u"project_assignement"),
    u"_users": DBApi(DB, u"_user"),
    u"task-lists": DBApi(DB, u"task_list"),
    u"tasks": TaskDBApi(DB, MAIL_IO, NOTIFICATION_CONFIG),
    u"comments": CommentDBApi(DB, MAIL_IO, NOTIFICATION_CONFIG),
    u"tags": DBApi(DB, u"tag"),
    u"task-tags": DBApi(DB, u"task_has_tag"),
    u"clients_affected_to_users": DBApi(DB, u"clients_affected_to_users"),
    u"project_consumption": DBApi(DB, u"project_consumption"),
    u"project_consumption_per_user": DBApi(DB,
                                           u"project_consumption_per_user"),
    u"project-loads": DBApi(DB, u"project_load"),
    u"cras": DBApi(DB, u"cra"),
Ejemplo n.º 8
0
def main():  # pylint:disable=missing-docstring,too-many-locals

    log = logging.getLogger('gamebot_main')
    log.setLevel(MAIN_LOG_LEVEL)
    log_formatter = coloredlogs.ColoredFormatter(LOG_FMT)
    log_handler = logging.StreamHandler()
    log_handler.setFormatter(log_formatter)
    log.addHandler(log_handler)
    log.addHandler(
        logstash.TCPLogstashHandler(LOGSTASH_IP, LOGSTASH_PORT, version=1))

    log.info("Starting GameBot")
    db_api = DBApi()

    # Check DB connection.
    while True:
        if db_api.check_connection():
            log.info("Connection to DB Verified.")
            break
        else:
            log.fatal("Looks like DB is Down. Unable to verify db connection.")
            time.sleep(5)

    scripts_interface = ScriptsFacade(db_api)
    log.info("Initialization Complete")
    log.info("Check to see if there's a game running")

    while True:
        current_game_id = db_api.get_game_state()
        if current_game_id is None:
            log.info("Game is paused or hasn't started yet, retrying...")
            time.sleep(10)
            continue

        current_tick, seconds_left = db_api.get_current_tick_info()

        if current_tick != 0:
            log.info("We must be picking up from the last run. "
                     "Sleep for {} seconds until the next tick.".format(
                         seconds_left))
            time.sleep(seconds_left)

        log.warning("Starting Main Loop")
        tick_id = current_tick

        while True:
            log.info("Starting Iteration")

            current_game_id = db_api.get_game_state()
            if current_game_id is None:
                log.info("Game is paused, breaking out of main loop")
                break

            # Create a new tick and decide what scripts to run against each team
            sleep_time, num_benign, num_exploit, num_get_flags = _get_ticks_configuration(
                db_api)

            # Update script to be run, we should update these first as scriptbot
            # waits for tick to pick up the scripts.
            # First, update scripts and then update tick so that
            # when the tick is updated,
            # scriptbot can get all the scripts in a single shot.
            if scripts_interface.update_scripts_to_run(tick_id + 1, num_benign,
                                                       num_exploit,
                                                       num_get_flags):
                log.info("Successfully updated scripts to run for:" +
                         str(tick_id + 1))
            else:
                log.error("Failed to update scripts to run for:" +
                          str(tick_id + 1))

            # Change the tick
            current = datetime.now()
            time_to_change = current + timedelta(seconds=sleep_time)

            tick_id = db_api.update_tick_info(time_to_change.isoformat(),
                                              current.isoformat())

            log.info("Current Tick {}".format(tick_id))
            log.info("Tick Configuration, Sleep Time:" + str(sleep_time) +
                     ", num_benign:" + str(num_benign) + ", num_exploit:" +
                     str(num_exploit) + ", num_get_flags:" +
                     str(num_get_flags))

            # compute scores for the previous tick (the last completed tick)
            if tick_id > 1:
                # update the state of services for previous tick
                old_time = datetime.now()
                log.info("Updating state of services across all teams.")
                scripts_interface.update_state_of_services(tick_id - 1)
                log.info("Updated state of services across all teams in:" +
                         str(datetime.now() - old_time))
            else:
                log.info("Ignoring Scoring, as this is first tick.")

            # Sleep for the amount of time until the next tick
            time_diff_to_sleep = time_to_change - datetime.now()
            if time_diff_to_sleep.total_seconds() < 0:
                log.warning(
                    "Not sleeping at all. I was {} seconds too slow".format(
                        time_diff_to_sleep))
            else:
                seconds_to_sleep = (time_diff_to_sleep.seconds +
                                    (time_diff_to_sleep.microseconds / 1E6))
                log.info("Sleeping for:" + str(seconds_to_sleep))
                time.sleep(seconds_to_sleep)
                log.info("Awake")
Ejemplo n.º 9
0
import pandas
import warnings
import re
from dbapi import DBApi

BASE = os.getcwd()

# OLD_LINKS = "/home/garrison/Cloud/work/chords/util/export-post-2019-01-12_19-48-44.csv"
OLD_ARTIST = os.path.join(BASE, "util/check-chords-art+song.csv")
OLD_CONTENT = os.path.join(BASE, "util/URL-content.csv")

IN_DIR = os.path.join(BASE, "util/data_to_load")
OUT_DIR = os.path.join(BASE, "util/data_in_db")

# db = DBApi()
db = DBApi()


def read_old():
    r = re.compile("<iframe.*>.*</iframe?>")
    r_div = re.compile("<div.*?>")
    df_content = pandas.read_csv(OLD_CONTENT)
    df_artist = pandas.read_csv(OLD_ARTIST)
    songs = {}
    for index, row in df_artist[df_artist["Песня"].notnull()].iterrows():
        url = row["Old URL"]
        songs[url] = {"song_name": row["Песня"], "artist_name": row["Группа"]}
        if not pandas.isnull(row["Title"]):
            songs[url]["seo_title"] = row["Title"]
        if not pandas.isnull(row["Description"]):
            songs[url]["seo_description"] = row["Description"]
Ejemplo n.º 10
0
from dbapi import DBApi

oracledb = DBApi("<USER>", "<PASS>")
oracledb.disconnect()
Ejemplo n.º 11
0
class Sterner:
    def __init__(self):
        self.notify = Notify('Sterner.log')

        #database api
        self.db_api = DBApi()

        #start network server
        self.network = SternerNetwork(self, self.notify, self.db_api)
        self.network.startServer()

        #dict to save logged in players
        # K: player_id , V: panda connection
        self.logged_in_players = {}

        self.notify.info("Sterner started.")

        #so we dont have different versions of games all at once
        self.db_api.finishAllGamesExceptVersion(COMMUNICATION_PROTOCOL_VERSION)

        #dequeue for sending msgs to network... format:(player_id, (msg))
        self.to_network = collections.deque()

        #dequeue for sending messages for engines and EngineHandlerThread, if msg[0] == STERNER_ID, than it is for handler
        self.msgs4engines = collections.deque()

        #dequeue in which EngineHandlerThread puts messages for Sterner
        self.fromHandler = collections.deque()

        self.engine_handler = EngineHandlerThread(self.fromHandler,
                                                  self.msgs4engines,
                                                  self.to_network, self.notify,
                                                  self.db_api)
        self.engine_handler.start()

    def start(self):

        #for time limit - debug option if we want to stop sterner automatically after some time
        t = time.time()

        #-----------================------main loop---------=====================---------
        #-----------================------main loop---------=====================---------
        #-----------================------main loop---------=====================---------
        while True:

            #get msg from network
            tmp_msg = self.network.readMsg()

            if tmp_msg:
                #print "sterner dobio:",tmp_msg
                try:
                    msg, source = tmp_msg

                    #check if this message is for sterner or not
                    if msg[0] == STERNER_ID:
                        self.handleSternerMsg(msg[1:], source)
                    else:
                        self.msgs4engines.append(msg)
                except:
                    self.notify.error("Error with message:%s\ninfo:%s",
                                      str(tmp_msg), traceback.format_exc())

            #check to_network for messages, and if there are any send them to players
            try:
                while True:
                    player_id, game_id, msg = self.to_network.popleft()
                    conn, in_game_id = self.logged_in_players[player_id]
                    if conn and game_id == in_game_id:
                        self.network.sendMsg(msg, conn)
            #IndexError if there is nothing to pop
            #KeyError if engine is sending messages to disconnected/unknown players, we just ignore this
            except (IndexError, KeyError):
                pass

            #check for messages from Handler
            try:
                while True:
                    msg = self.fromHandler.popleft()
                    self.handleHandlerMessage(msg)
            except IndexError:
                pass

            #behave nicely with cpu
            time.sleep(0.1)

            #if we set the option for sterner auto shutdown, check the time period
            if STERNER_TIME_LIMIT and time.time() - t > STERNER_TIME_LIMIT:
                break
        #---------================--------main loop--------==================----------
        #---------================--------main loop--------==================----------
        #---------================--------main loop--------==================----------

        #shutdown everything we can
        self.engine_handler.stop = True
        self.network.stopServer()

        time.sleep(3)

    def handleHandlerMessage(self, msg):

        if msg[0] == NEW_GAME_STARTED:
            player_id = msg[1]
            game_id = msg[2]
            #try to find logged in player, if we cannot, just return
            source = self.getConnectionFromId(player_id)

            if not source:
                print "NIST PRIST"
                return

            #we don't know if it was a public game or private game so refresh both lists
            self.network.sendMsg(
                (MY_WAITING_GAMES, self.db_api.getMyWaitingGames(player_id)),
                source)
            self.network.sendMsg(
                (EMPTY_PUBLIC_GAMES, self.db_api.getAllEmptyPublicGames()),
                source)

    #K-player_id - V:(connection, game_id)
    def getConnectionFromId(self, player_id):
        try:
            return self.logged_in_players[player_id][0]
        except:
            return None

    def getIdFromConnection(self, connection):
        for player_id in self.logged_in_players.keys():
            if self.logged_in_players[player_id][0] == connection:
                return player_id
        return None

    def handleSternerMsg(self, message, connection):

        if message[0] == START_NEW_GAME:
            level = message[1]
            budget = message[2]
            player_ids = message[3]
            public_game = message[4]
            game_name = message[5]
            player_id = self.getIdFromConnection(connection)

            #DEBUG: this is for setting up local test game
            if public_game == -1:
                self.msgs4engines.append(
                    (STERNER_ID, START_NEW_GAME, -1, player_id))
                return

            #check if there are at least 2 players
            if len(player_ids) < 2:
                self.network.sendMsg((ERROR, "Not enough players"), connection)
                return

            #check if level is ok
            all_levels = self.db_api.getAllLevels()
            if level not in all_levels:
                self.network.sendMsg((ERROR, "Wrong level"), connection)
                return

            #TODO: krav: check if budget is ok

            #if this is a private game check if player_ids are ok
            if not public_game:
                all_player_ids = [
                    int(x) for x, y in self.db_api.getAllPlayers()
                ]
                for p_id in player_ids:
                    if p_id not in all_player_ids:
                        self.network.sendMsg(
                            (ERROR, "Wrong player id:%d" % p_id), connection)
                        return
            #if public game, game creator's id must be one of the players, all others must be 0
            else:
                if player_id not in player_ids:
                    self.network.sendMsg((ERROR, "You have to be in the game"),
                                         connection)
                    return
                tmp_player_ids = player_ids[:]
                tmp_player_ids.remove(player_id)

                for p in tmp_player_ids:
                    if p != 0:
                        self.network.sendMsg((
                            ERROR,
                            "You cannot assign players other than yourself in public games"
                        ), connection)
                        return

            #check game name
            if not game_name:
                if not public_game:
                    game_name = 'Private game on ' + level
                else:
                    game_name = 'Public game on ' + level

            #create the game and all players in the database, set game creator accept status to 1
            game_id = self.db_api.createGame(level, budget, player_id,
                                             datetime.datetime.now(),
                                             COMMUNICATION_PROTOCOL_VERSION,
                                             public_game, game_name)
            for i in xrange(0, len(player_ids)):
                if player_ids[i] == player_id:
                    self.db_api.addPlayerToGame(game_id, player_ids[i], i, i,
                                                1)
                else:
                    self.db_api.addPlayerToGame(game_id, player_ids[i], i, i,
                                                0)

            self.msgs4engines.append(
                (STERNER_ID, START_NEW_GAME, game_id, player_id))
            return

        elif message[0] == ALL_FINISHED_GAMES:
            self.network.sendMsg(
                (ALL_FINISHED_GAMES, self.db_api.getAllFinishedGames()),
                connection)
            return

        elif message[0] == ENTER_GAME:
            game_id = message[1]

            player_id = self.getIdFromConnection(connection)
            self.logged_in_players[player_id] = (connection, game_id)

            self.msgs4engines.append((game_id, player_id, ENTER_GAME, game_id))
            return

        elif message[0] == REFRESH_MY_GAME_LISTS:
            self.sendSternerData(connection)
            return

        elif message[0] == DECLINE_GAME:
            game_id = message[1]
            player_id = self.getIdFromConnection(connection)

            game = self.db_api.getGame(game_id, filter=True)

            #if there is no such game
            if not game:
                self.network.sendMsg((ERROR, "No such game."), connection)
                return

            #if this is a public game, you cant decline that
            if game[9]:
                self.network.sendMsg(
                    (ERROR,
                     "You cannot decline public games, just don't join :)"),
                    connection)
                return

            #if this game already started
            if game[5] != 0:
                self.network.sendMsg((
                    ERROR,
                    "This game already started, if you want to concede do it from inside the game"
                ), connection)
                return

            #if you are not a player in this game
            game_player = self.db_api.getGamePlayer(game_id, player_id)
            if not game_player:
                self.network.sendMsg((
                    ERROR,
                    "You cannot decline, you are not even part of this game!"),
                                     connection)
                return

            #ok so delete the game
            self.db_api.deleteGame(game_id)

            #refresh his unaccepted games list
            self.network.sendMsg((MY_UNACCEPTED_GAMES,
                                  self.db_api.getMyUnacceptedGames(player_id)),
                                 connection)

        elif message[0] == ACCEPT_GAME:
            game_id = message[1]
            player_id = self.getIdFromConnection(connection)

            game = self.db_api.getGame(game_id)

            #if there is no such game
            if not game:
                self.network.sendMsg((ERROR, "No such game."), connection)
                return

            #check if this game already started or is finished
            if game[5] == 1:
                self.network.sendMsg((ERROR, "Game already started"),
                                     connection)
                return
            elif game[5] == 2:
                self.network.sendMsg((ERROR, "Game finished"), connection)
                return

            #if this is a public game
            if game[9]:
                #if we are already in this game, return error
                game_player = self.db_api.getGamePlayer(game_id, player_id)
                if game_player:
                    self.network.sendMsg(
                        (ERROR, "You are already in this game"), connection)
                    return

                #find first empty slot, set this players id in its stead
                game_player = self.db_api.getGamePlayer(game_id, 0)
                game_player[2] = player_id
                #we update game_player later

            #if this is a private game
            else:
                #check if this player really did not accept this game yet
                game_player = self.db_api.getGamePlayer(game_id, player_id)
                if game_player[5] == 1:
                    self.network.sendMsg((ERROR, "Already accepted this game"),
                                         connection)
                    return

            #update this player's acceptance, for both cases (public/private game)
            game_player[5] = 1
            self.db_api.updateGamePlayer(game_player)

            #we accepted this game
            self.network.sendMsg((ACCEPT_GAME, game_id), connection)

            #refresh unaccepted games list
            self.network.sendMsg((MY_UNACCEPTED_GAMES,
                                  self.db_api.getMyUnacceptedGames(player_id)),
                                 connection)

            #try to see if this is the last player accepting and if so start the game
            #if at least 1 player did not accept, return
            for player in self.db_api.getGameAllPlayers(game_id):
                if player[5] == 0:
                    #refresh waiting games list
                    self.network.sendMsg(
                        (MY_WAITING_GAMES,
                         self.db_api.getMyWaitingGames(player_id)), connection)
                    return

            #ok all players accepted, start this game
            game[5] = 1
            self.db_api.updateGame(game)

            #refresh active games
            self.network.sendMsg(
                (MY_ACTIVE_GAMES, self.db_api.getMyActiveGames(player_id)),
                connection)
            return

        elif message[1] == PING:
            print "ping:", message
            self.network.sendMsg((PONG, message[2]), connection)
            return

        else:
            self.notify.error("Undefined message:%s", str(message))

        pass

    def sendSternerData(self, source):
        player_id = self.getIdFromConnection(source)
        self.network.sendMsg((ALL_PLAYERS, self.db_api.getAllPlayers()),
                             source)
        self.network.sendMsg((ALL_LEVELS, self.db_api.getAllLevels()), source)

        #DEBUG: add local test game
        active_games = self.db_api.getMyActiveGames(player_id)
        active_games.insert(0, (-1, "assassins2", 1000, 1, 22, 0, 0, 0, '0.1',
                                0, "--------local test game-------", 0, 0))
        self.network.sendMsg((MY_ACTIVE_GAMES, active_games, source))

        self.network.sendMsg(
            (MY_UNACCEPTED_GAMES, self.db_api.getMyUnacceptedGames(player_id)),
            source)
        self.network.sendMsg(
            (MY_WAITING_GAMES, self.db_api.getMyWaitingGames(player_id)),
            source)
        self.network.sendMsg(
            (EMPTY_PUBLIC_GAMES, self.db_api.getAllEmptyPublicGames()), source)
        self.network.sendMsg((NEWS_FEED, self.db_api.getLast3News()), source)

    def playerConnected(self, player_id, source):
        #if this player already has a connection, disconnect him
        if player_id in self.logged_in_players:
            conn = self.getConnectionFromId(player_id)
            if conn:
                self.network.disconnect(conn)

        #remember this player-connection
        self.logged_in_players[player_id] = (source, 0)

        #send this new player everything he needs
        self.sendSternerData(source)

    def playerDisconnected(self, source):
        #go through all logged in players
        for pid in self.logged_in_players.keys():

            #if we find the one with this connection
            if self.logged_in_players[pid] == source:

                #remove him from the dict
                del self.logged_in_players[pid]
                return