Ejemplo n.º 1
0
def swap(con, msg):
    if len(
            msg
    ) > 2:  #if length is greater than 2 or less than 2, it wasn't a proper message
        send_strike(con, 32)
        return
    elif len(msg) < 2:
        send_strike(con, 34)
        return
    else:
        try:  # attempt to convert it to an integer
            returncard = int(msg)
        except:  # if unable to, send a strike
            send_strike(con, 30)
            return  # if there is no player 1, or this isn't player 1, send strike then the hand if necessary
        if not Table.player[1] or not Table.player[1].equals(con):
            send_strike(con, 71)
            server_hand(con)
            return  # if we don't want to receive a swap message right now, send a strike
        if gvals.state != 2:
            send_strike(con, 72)
            server_hand(con)
            return  # if player 1 doesn't have the card, send strike and update their timeout timer
        if not returncard in Table.handof[1]:
            strike(Table.player[1], 70)
            Table.sendhand(con, Table.handof[1])
            gvals.to_time = time.time()
            return
        else:  # otherwise, remove it from player 1's hand, append it to player 7's hand, sort 7
            Table.handof[1].remove(returncard)
            Table.handof[7].append(returncard)
            Table.handof[7].sort()
            try:  # send the swap message to the scumbag so they know what they lost and what they received
                Table.player[7].socket.send("[swaps|%02d|%02d]" %
                                            (returncard, Table.wcard))
            except socket.error:
                Table.passof[7] = 2
                Table.numplayers -= 1
                Table.getNextPlayer()
            gvals.state = D_STATE.WAITPLAY  # state is then put into the waiting for play state
            Table.StartGame()  # and we start the game
Ejemplo n.º 2
0
def main():
    keepalive = 1  # Variable for keeping the server running.
    HOST = ''  # Localhost
    PORT = 36789  # Port number
    BLOG = 5  # Number of concurrent listens
    SIZE = 4096  # Size of data for receiving data

    # Command line argument parser.
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-l",
        dest="l",
        type=int,
        default=D_LTIME,
        help="Sets the lobby timeout value (going from no game -> new game).")
    parser.add_argument(
        "-t",
        dest="t",
        type=int,
        default=D_TIMEO,
        help="Sets the timeout value (for plays/warlord swap).")
    parser.add_argument(
        "-m",
        dest="m",
        type=int,
        default=D_MINPL,
        help="Sets the minimum number of players for a game to run.")
    parser.add_argument(
        "-s",
        dest="s",
        type=int,
        default=D_STRIK,
        help=
        "Sets the number of strikes given out before disconnecting a client.")
    parser.add_argument(
        "-c",
        dest="c",
        type=int,
        default=D_CONNS,
        help="Sets the maximum number of clients allowed in the lobby.")
    args = parser.parse_args()

    # Set values based on command line (or default values if none specified.)
    gvals.ltimeout = args.l
    gvals.timeout = args.t
    if args.m >= 3 and args.m <= 7:
        gvals.minplay = args.m
    elif args.m < 3:
        print "Minimum number of players to start a game must be 3 or greater. Setting value to 3."
        gvals.minplay = 3
    else:
        print "Maximum number of players for a game is 7. Useless it is to wait for more than 7. Setting to 7."
        gvals.minplay = 7
    if args.l < 35:
        gvals.maxclients = 35
    elif args.l > 90:
        gvals.maxclients = 90
    else:
        gvals.maxclients = args.l
    gvals.strikeout = args.s if args.s < 10 else 9  # strikes must be a single digit, i.e. max of 9

    try:  # attempt to open the socket we need
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # the next line allows us to re-establish the socket immediately after closing
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server.bind((HOST, PORT))
        server.listen(BLOG)
        inlist.append(
            server)  # ensure that we're listening to the socket we opened
    except socket.error:  # unable to establish the socket
        print "Unable to establish socket. Terminating."
        server.close()  # ensure that we closed the server
        return

    print "Server live at " + str(socket.gethostbyname(socket.gethostname()))
    print "Clients connected: 0"
    print "----------------------------------"

    gvals.state = D_STATE.WAITMIN  # set default state to waiting for min players

    # Create queue for reading system in.
    inputQueue = Queue.Queue()
    lock = threading.Lock()
    inThread = threading.Thread(target=input_thread, args=(
        inputQueue,
        lock,
    ))
    inThread.daemon = True
    inThread.start()

    while keepalive:
        try:
            # use select statement, don't want it blocking for more than a second at any time
            inready, outready, exceptready = select.select(inlist, [], [], 1.0)
        except select.error:
            print "Unable to use select statement."
            break
        lock.acquire()
        while (not inputQueue.empty()):  #check for quit command from terminal
            line = inputQueue.get().strip()
            if line == 'quit' or line == 'q':
                keepalive = 0
        lock.release()
        for s in inready:  # loop through all of the sockets with information ready to be read
            if s == server:  # if the socket is our first socket, we're accepting the connection for a new client
                try:  # attempt to accept the connection, then add it input list
                    client, address = server.accept()
                    inlist.append(client)
                    print "Clients connected: " + str(len(inlist) - 1)
                    print "----------------------------------"
                except socket.error:
                    print "Unable to accept client connection."
            else:  # otherwise we had someone sending us a message!
                try:
                    data = s.recv(SIZE,
                                  socket.MSG_PEEK)  # it is christmas! peek!
                    newdata = data.replace('\n', '').replace(
                        '\r', '')  # check to see if its just \n or \r
                    if len(data) > 0 and newdata == '':
                        data = s.recv(len(data))  # pull out if so
                    elif newdata:  # check newline for correct messages
                        data = data.replace('\n', ' ').replace(
                            '\r', ' ')  # replace \n and \r in data
                        peek = RE_CHKMSG.match(data)  # peek = proper message
                        throwaway = RE_CHKLEN.match(
                            data)  # throwaway = some string before [
                        if throwaway and throwaway.group(
                                "len"):  # if we have something to throwaway
                            data = s.recv(
                                len(throwaway.group("len")
                                    ))  # pull it from the buffer (and only it)
                            tdata = data.replace('\n', '').replace('\r', '')
                            if tdata:  # check to see if it was just \n and \r
                                send_strike(
                                    s, 30
                                )  # if not, send strike to whomever this was
                        elif peek and peek.group(
                                "chk"
                        ):  # otherwise, if we had a properly formatted message
                            data = s.recv(len(
                                peek.group("chk")))  # pull it out
                            newdata = data.replace('\n', '').replace('\r', '')
                            parserecv(
                                s,
                                newdata)  # throw \n and \r away, then parse it
                        elif len(
                                newdata
                        ) > 512:  # if we've gotten 512 characters, and no [], then throw it all away
                            data = s.recv(SIZE)
                            send_strike(s, 30)  # and send a strike
                    elif not data:
                        close(s)  # if they send us nothing, we close them
                except socket.error:  # on socket error, we close them
                    close(s)
                    continue
        # Check the state, and do the appropriate action.
        if gvals.state == D_STATE.WAITMIN:  # check if we're waiting for the minimum number of players before starting
            if len(gvals.lobby
                   ) >= gvals.minplay:  # check number of players in lobby
                gvals.state = D_STATE.LTIMEOUT  # set state to lobby timeout state (waiting for set time before starting)
                gvals.to_time = time.time()  # recording current time
                print "Play starting in " + str(gvals.ltimeout) + " seconds."
                print "----------------------------------"
        elif gvals.state == D_STATE.LTIMEOUT:  # if we're waiting for a specified time
            curtime = time.time()  # get current time
            if curtime > gvals.to_time + gvals.ltimeout:  # if we're less than the recorded time + timeout value, do nothing
                print "Let the game begin!"
                print "----------------------------------"
                Table.notranked = 1  # make sure when going from lobby timeout to new hand we're doing unranked
                Table.newhand()  # else start a new hand
        elif gvals.state == D_STATE.WTIMEOUT:  # waiting for warlord message
            Table.checkPlayers()  # update the number of players at the table
            if Table.numplayers == 0:  # if everyone left we can go to the waiting for players state
                gvals.state = D_STATE.WAITMIN
                print "No players at table. Waiting for players."
                print "----------------------------------"
            else:  # otherwise check the time
                rightnow = time.time()
                if (gvals.timeout > 0
                        and rightnow > gvals.to_time + gvals.timeout
                    ) or Table.player[1] not in gvals.clientlist:
                    strike(
                        Table.player[1], 20
                    )  # we haven't received a message yet, strike the player (warlord is default player 1)
                    if Table.passof[
                            1] == 2:  # if they're dead, we need to get the next player, because they were set as current player
                        Table.getNextPlayer()
                    if Table.wcard in Table.handof[
                            1]:  # remove wcard if we had it in their hand
                        Table.handof[1].remove(Table.wcard)
                    Table.handof[7].append(
                        Table.wcard
                    )  # put the 'wcard' back in the scumbag's hands
                    Table.handof[7].sort()
                    Table.player[7].socket.send("[swaps|52|52]")
                    Table.StartGame()  # start the game
        elif gvals.state == D_STATE.WAITPLAY:  # waiting for current player to send their play message
            Table.checkPlayers()  # check how many players we have
            if Table.numplayers == 0:  # if none, wait for new players
                print "No players at table. Waiting for players."
                print "----------------------------------"
                gvals.state = D_STATE.WAITMIN
            elif Table.passof[
                    Table.
                    curplayer] == 2:  # if the player died, get the next player and play
                Table.getNextPlayer()
                Table.Play()
            else:  # otherwise, check the time and strike if necessary
                rightnow = time.time()
                if gvals.timeout > 0 and rightnow > gvals.to_time + gvals.timeout:
                    strike(Table.player[Table.curplayer], 20)
                    Table.passof[Table.curplayer] = 1 if Table.passof[
                        Table.
                        curplayer] != 2 else 2  # set pass value to pass or dead, whichever applies
                    Table.getNextPlayer()  # get next player
                    if gvals.state == D_STATE.WAITPLAY:  # if we're still in the waiting for play state, we can play
                        Table.Play()
        elif gvals.state == D_STATE.NEWGAME:  # we need to start a new hand
            print "A new round is now starting."
            print "----------------------------------"
            Table.notranked = 0  # this state is only entered into if we were in a hand already, so by default it is ranked
            Table.newhand()

    for c in gvals.clientlist:  # send quit message to everyone
        try:
            c.socket.send("[squit]\n")
        except socket.error:  # close the socket of anyone who can't have the message sent to them
            close(c.socket)
    server.close()  # we've exited our run loop, so close the socket