def send_peer_to_peer_info(self):
     for peer in self.peers:
         dataSend = protocol_message.construct_peer_to_peer_info_data(
             peer['neighbors'], peer['user_id'])
         message_send = protocol_message(protocol_message.TYPE_P2P_INFO,
                                         len(dataSend), dataSend)
         peer['connection'].send(message_send.collapsed())
 def response_message(self):
     dataSend = protocol_message.construct_p2p_response_data(
         self.peer.getsockname()[0],
         self.peer.getsockname()[1])
     message_send = protocol_message(protocol_message.TYPE_P2P_RESPONSE,
                                     len(dataSend), dataSend)
     return message_send
def main():
    port = 9071
        
    try:
        options, args = getopt.getopt(sys.argv[1:], 'p:')
        port_selection = filter(lambda x: "-p" in x, options)
        if len(port_selection) > 0:
            port = int(port_selection[0][1])
    except (getopt.GetoptError, IndexError):
        usage()
        exit()

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print 'Socket created'

    server.bind(('', port))
    server.listen(5)

    Height = 5
    Width = 10
    masterBoard = board(Width, Height)
    clients = []
    message_id = 0
    
    client_info_list = []
    num_users = 0

    while True:
        Connections, wlist, xlist = select.select([server], [], [], 0.05)

        for Connection in Connections:
            client, Informations = Connection.accept()
            clients.append(client)
            client_info_list.append({'user_id': num_users, 'connection': client, 'connected': True})
            num_users += 1
            print clients
            # Test peer to peer mode init on every new client
            #print "P2P"
            #p2p_mode(client_info_list)

        clientsList = []
        try:
            clientsList, wlist, xlist = select.select(clients, [], [], 0.05)
        except select.error:
            pass
        else:
            for clientInList in clientsList:
                dataRec = clientInList.recv(1024)
                #print "Got: "
                #print dataRec
                message_rec = protocol_message.message_from_collapsed(dataRec)
                if(message_rec.type == protocol_message.TYPE_NEW_USER):
                    user_id_index = next(index for (index, d) in enumerate(client_info_list) if d['connection'] == clientInList)
                    print "User id:"
                    print client_info_list[user_id_index]['user_id']
                    dataSend = protocol_message.construct_welcome_message_data(client_info_list[user_id_index]['user_id'])
                    message_send = protocol_message(protocol_message.TYPE_WELCOME, len(dataSend), dataSend)
                    clientInList.send(message_send.collapsed())

                if(message_rec.type == protocol_message.TYPE_UPDATE_BOARD):
                    print("Got update board")
                    print(message_rec.message)
                    #send the board back
                    dataSend = message_rec.message
                    #message_id += 1
                    message_send = protocol_message(protocol_message.TYPE_UPDATE_BOARD, len(dataSend), dataSend)
                    notify_all_clients(clients, message_send)
                if(message_rec.type == protocol_message.SENTINEL):
                    clients.remove(clientInList)
                    # TODO add this client to a waiting to be reconnected list
                if(message_rec.type == protocol_message.TYPE_P2P_REQUEST):
                    p2p = p2p_mode(client_info_list)
                    p2p.send_peer_to_peer_notification()

                if(message_rec.type == protocol_message.TYPE_P2P_RESPONSE):
                    user_id_index = next(index for (index, d) in enumerate(client_info_list) if d['connection'] == clientInList)
                    connection = {}
                    connection['user_id'] = client_info_list[user_id_index]['user_id']
                    connection['addr'] = message_rec.p2p_response_data_address()
                    connection['port'] = message_rec.p2p_response_data_port()
                    p2p.add_connection_data(connection.copy())
                    if (p2p.ready()):
                        p2p.send_peer_to_peer_info()
                    
    clientInList.close()
    server.close()
def main(stdscr):
        
        port = 9071

        in_p2p_mode = False
        
        try:
                options, args = getopt.getopt(sys.argv[1:], 'p:')
                port_selection = filter(lambda x: "-p" in x, options)
                if len(port_selection) > 0:
                        port = int(port_selection[0][1])
        except (getopt.GetoptError, IndexError):
                usage()
                return()
        
        #curses set up
        curses.noecho()
        curses.init_pair(1, curses.COLOR_MAGENTA, curses.COLOR_BLACK)
        curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK)
        curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK)
        curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK)
        curses.curs_set(0)
        stdscr.nodelay(True)
        
        #server setup
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.connect(('127.0.0.1', port)) 

        peer_connections = [server]
        
        #send new user message
        dataString = "New User"
        dataSend = protocol_message(protocol_message.TYPE_NEW_USER, len(dataString), dataString)
        server.send(dataSend.collapsed())
        z = 0
        while True:
                if in_p2p_mode:
                        Connections, wlist, xlist = select.select([p2p_connection.connection()], [], [], 0.05)
                        for Connection in Connections:
                                Peer, info = Connection.accept()
                                peer_connections.append(Peer)

                read_list = []
                if not in_p2p_mode:
                        read_list = [server]
                else:
                        read_list = peer_connections
                 
                rlist, wlist, xlist = select.select(read_list, [], [], 0)
                for item in rlist: 
                        if item == server or True:
                                dataRec = item.recv(1024)
                                message_rec = protocol_message.message_from_collapsed(dataRec)
                                
                                if(message_rec.type == protocol_message.TYPE_WELCOME):
                                        #board set up
                                        userNum = message_rec.welcome_message_user_id()
                                        Height = 5
                                        Width = 10
                                        canvas = board(Width, Height) #TODO get width and height from server
                                        canvas.addUser(userNum)
                                        startScreen(canvas, stdscr)
                                        printBoardClient(canvas, stdscr)

                                if(message_rec.type == protocol_message.TYPE_UPDATE_BOARD):
                                        z += 1
                                        canvas.stringToBoardFromServer(message_rec.message)
                                        printBoardClient(canvas, stdscr)
                                        # if(canvas.stringToBoardFromServer(message_rec.message) == -1):
                                        #         debugMsg("error recv board", z, stdscr)
                                        #         z += 1
                                        #printBoardClient(canvas, stdscr)
                                        if in_p2p_mode:
                                                p2p_connection.forward_to_neighbors(message_rec)
                                if(message_rec.type == protocol_message.TYPE_P2P_NOTE):
                                        #in_p2p_mode = True
                                        p2p_connection = peer()
                                        server.send(p2p_connection.response_message().collapsed())
                                if(message_rec.type == protocol_message.TYPE_P2P_INFO):
                                        p2p_connection.add_neighbors(message_rec)
                                        in_p2p_mode = True
                        else:
                                dataRec = item.recv(1024)
                                        
                #get user input through the keyboard
                key = getInput(stdscr)
                if (key == -1):
                        continue
                
                if(key == ord("w") or key == ord("s") or key == ord("a") or key == ord("d") or key == curses.KEY_UP or key == curses.KEY_DOWN or key == curses.KEY_LEFT or key == curses.KEY_RIGHT):
                        #update our board and send it
                        newPos = posDelta(key)
                        canvas.moveUser(newPos)
                        boardString = canvas.boardToString()
                        message_send = protocol_message(protocol_message.TYPE_UPDATE_BOARD, len(boardString), boardString)
                        if not in_p2p_mode:
                                server.send(message_send.collapsed())
                        else:
                                p2p_connection.notify_neighbors(message_send)
                if(key == ord("p")):
                        #Request p2p mode
                        message_send = protocol_message(protocol_message.TYPE_P2P_REQUEST, 0, "")
                        server.send(message_send.collapsed())
 def send_peer_to_peer_notification(self):
     print "sending p2p note"
     for peer in self.peers:
         message_send = protocol_message(protocol_message.TYPE_P2P_NOTE, 0,
                                         "")
         peer['connection'].send(message_send.collapsed())