Esempio n. 1
0
    async def current(self, ctx: commands.Context):
        """Lists your current marble match

        Examples:
            - `$current`

        **Arguments**

        - `<ctx>` The context used to send confirmations.

        """
        logger.debug(f'current: {ctx}, {ctx.author}')

        # Gets player_id from ctx.author and gets match_id for player
        player_id = du.get_id_by_member(ctx, DbHandler.db_cnc, ctx.author)
        match_id = database_operation.find_match_by_player_id(DbHandler.db_cnc, player_id)
        logger.debug(f'player_id: {player_id}, match_id: {match_id}')

        # Checks if match_id is an actual id
        if not match_id:
            logger.debug('match_id is zero')
            await du.code_message(ctx, 'No current match')
            return
        # Gets match_info to display back to the user
        match_info = ma.get_match(ctx, match_id)  # database_operation.get_match_info_by_id(DbHandler.db_cnc, match_id)
        logger.debug(f'match_info: {match_info}')

        # Get Accounts of both participants
        player_info1 = acc.get_account_from_db(ctx, DbHandler.db_cnc, match_info.challenger.id)  # database_operation.get_player_info(DbHandler.db_cnc, match_info[3])
        player_info2 = acc.get_account_from_db(ctx, DbHandler.db_cnc, match_info.recipient.id)  # database_operation.get_player_info(DbHandler.db_cnc, match_info[4])
        logger.debug(f'player_info1: {player_info1}, player_info2: {player_info2}')

        await du.code_message(ctx, f'Match between {player_info1.nickname} and '
                                   f'{player_info2.nickname} for {match_info.amount} marbles'
                                   f'\nMatch ID: {match_info.id}')
Esempio n. 2
0
    async def close_current_match(self, ctx: commands.Context):
        """Closes your active marble match

        Examples:
            - `$close`

        **Arguments**

        - `<ctx>` The context used to send confirmations

        """
        logger.debug(f'close: {ctx}, {ctx.author}')

        # Gets player_id and match_id, to close the current match
        player_id = du.get_id_by_member(ctx, DbHandler.db_cnc, ctx.author)
        match_id = database_operation.find_match_by_player_id(DbHandler.db_cnc, player_id)
        logger.debug(f'player_id: {player_id}, match_id: {match_id}')

        # Gets match_info to return marbles back to participants
        match_info = ma.get_match(ctx, match_id)  # database_operation.get_match_info_by_id(DbHandler.db_cnc, match_id)
        logger.debug(f'match_info: {match_info}')

        player2_refund = False

        # Checks if match is accepted by participant2
        if match_info.accepted:  # Match is accepted
            # Gets participant2's Account to change marbles
            player2 = acc.get_account_from_db(ctx, DbHandler.db_cnc, match_info.recipient.id)
            logger.debug(f'player2: {player2}')
            # Checks if player2 is 0, then returns if 0
            if not player2:
                logger.debug(f'Unable to get participant2 Account')
                await du.code_message(ctx, 'Unable to get participant2\'s account')
                return
            # Sets flag for player2 to be refunded amount to true
            player2_refund = True
            logger.debug(f'player2_refund: {player2_refund}')

        # Get participant1's Account to refund player for match amount
        player1 = acc.get_account_from_db(ctx, DbHandler.db_cnc, match_info.challenger.id)
        # Check if player1 is 0, then returns if 0
        if not player1:
            logger.debug('Unable to get participant1 Account')
            await du.code_message(ctx, 'Unable to get participant1\'s account')
            return

        # Deletes the match and all the bets on the match by id, checks if write was successful and returns message
        if not database_operation.delete_match(DbHandler.db_cnc, match_id):
            logger.debug('Unable to delete match')
            await du.code_message(ctx, 'Unable to delete match', 3)
            return

        # Refunds players marbles, checks if player2 flag is true to refund player2
        player1.marbles += match_info.amount
        if player2_refund:
            player2.marbles += match_info.amount

        database_operation.delete_bet_by_match_id(DbHandler.db_cnc, match_id)
        await du.code_message(ctx, f'Closed match {match_id}.')
Esempio n. 3
0
    async def accept(self, ctx: commands.Context):
        """Accepts a match you were challenged to

        Examples:
            - `$accept`

        **Arguments**

        - `<ctx>` The context used to send confirmations.

        """
        logger.debug(f'accept: {ctx}, {ctx.author}')
        # Get player from database for user, then get a match_id
        player = acc.get_account(ctx, DbHandler.db_cnc, ctx.author)
        match_id = database_operation.find_match_by_player_id(DbHandler.db_cnc, player.id)
        logger.debug(f'player: {player}, match_id: {match_id}')

        # Checks if match id is 0/None, gives user message and returns to exit
        if not match_id:
            logger.debug(f'match_id is zero')
            await du.code_message(ctx, 'You don\'t have a match to accept')
            return

        # Get match_info to get marble amount
        match = ma.get_match(ctx, match_id)  # database_operation.get_match_info_by_id(DbHandler.db_cnc, match_id)

        # Checks if match_info is valid
        if not match:
            logger.debug('match_info is zero')
            await du.code_message(ctx, 'Unable to get match info')
            return

        # Check if user accepting is participant2
        if player.id != match.recipient.id:
            logger.debug(f'{ctx.author} tried to accept a match they aren\'t the recipient of')
            await du.code_message(ctx, 'You\'re not the recipient of a match')
            return

        # Updates match accepted flag in database, checks if write was successful and gives message
        try:
            match.accepted = True  # database_operation.update_match_accepted(DbHandler.db_cnc, match_id):
        except commands.CommandError as e:
            logger.debug(f'Unable to update match accepted flag')
            await du.code_message(ctx, 'Was unable to accept match', 3)
            return

        # Subtracts marbles from user
        player.marbles -= match.amount

        await du.code_message(ctx, f'Match {match.id} accepted, now open for betting.'
                                   f'\nType \'$start\' to close the betting and start the match')
Esempio n. 4
0
    async def match_start(self, ctx: commands.Context):
        """Starts a marble match

        Examples:
            - `$start`

        **Arguments**

        - `<ctx>` The context used to send confirmations.

        """
        logger.debug(f'match_start: {ctx}, {ctx.author}')
        # Get player_id from database for user, then get a match_id
        player_id = du.get_id_by_member(ctx, DbHandler.db_cnc, ctx.author)
        match_id = database_operation.find_match_by_player_id(DbHandler.db_cnc, player_id)
        logger.debug(f'player_id: {player_id}, match_id: {match_id}')

        # Checks if match id is 0/None, gives user message and returns to exit
        if not match_id:
            logger.debug(f'match_id is zero')
            await du.code_message(ctx, 'You don\'t have a match to start')
            return

        try:
            # Get match from match_id
            match = ma.get_match(ctx, match_id)
            logger.debug(f'match: {match}')
        except commands.CommandError as e:
            logger.error(f'Unable to get match from match_id')
            await du.code_message(ctx, 'Was unable to get match please try again later', 3)
            return

        # Check if match is accepted
        if not match.accepted:
            logger.debug(f'match.accepted is false')
            await du.code_message(ctx, 'You can only start matches the other player has accepted', 3)
            return

        # Updates match accepted flag in database, checks if write was successful and gives message
        try:  # if not database_operation.update_match_activity(DbHandler.db_cnc, match_id):
            match.active = True
        except commands.CommandError as e:
            logger.debug(f'Unable to update match accepted flag')
            await du.code_message(ctx, 'Was unable to accept match', 3)
            return
        await du.code_message(ctx, f'Match {match_id} started, betting is closed and all bets are locked in.')
Esempio n. 5
0
def get_bet(ctx: commands.Context,
            bet_id: int,
            history: bool = False) -> Union[Bet, int]:
    """Returns a Bet for Bet with bet_id

    **Arguments**
    - `<ctx>` Context used to get members and other information
    - `<bet_id>` Id of the bet to get
    - `<history>` Used to specify if you'd like to get a bet from bet_history or bets

    """
    logger.debug(f'get_bet: {bet_id}, {history}')

    # Check if ctx.channel is dm, return zero if true
    if isinstance(ctx.channel, discord.DMChannel):
        logger.error('ctx channel is dm, get_bet not allowed in dms')
        raise exception.DiscordDM

    # Declare bet_info to be filled later with a tuple of bet data from database
    bet_info = 0

    # Checks history to decide which table to get bet_info from
    if history:
        bet_info = database_operation.get_bet_history_info(
            DbHandler.db_cnc, bet_id)
    else:
        bet_info = database_operation.get_bet_info(DbHandler.db_cnc, bet_id)
    logger.debug(f'bet_info: {bet_info}')

    # Check if bet_info is zero, if true return. Is non zero when filled with data
    if not bet_info:
        logger.error(f'bet_info is zero')
        return 0

    # Get match from id in bet_info and validate
    match = matches.get_match(ctx, bet_info[2])
    logger.debug(f'match: {match}')
    if not match:
        logger.error('match is zero')
        raise exception.UnableToRead(class_='Match', attribute='match')

    # Get bettor from bet_info and validate
    bettor = account.get_account_from_db(ctx, DbHandler.db_cnc, bet_info[3])
    logger.debug(f'bettor: {bettor}')
    if not bettor:
        logger.error('bettor is zero')
        raise exception.UnableToRead(class_='Account', attribute='account')

    # Get bet_target from bet_info and validate
    bet_target = account.get_account_from_db(ctx, DbHandler.db_cnc,
                                             bet_info[4])
    logger.debug(f'bet_target: {bet_target}')
    if not bet_target:
        logger.error('bet_target is zero')
        raise exception.UnableToRead(class_='Account', attribute='account')

    # Check history to get data specific to history matches
    if history:
        logger.debug('history bet')

        # Get winner from bet_info and validate
        winner = account.get_account_from_db(ctx, DbHandler.db_cnc,
                                             bet_info[5])
        logger.debug(f'winner: {winner}')
        if not winner:
            logger.error('winner is zero')
            raise exception.UnableToRead(class_='Account', attribute='account')

        # Create Bet with bet_info data
        bet = Bet(bet_info[0], bet_info[1], match, bettor, bet_target, winner,
                  bet_info[6])
    else:
        bet = Bet(bet_info[0], bet_info[1], match, bettor, bet_target)
    logger.debug(f'bet: {bet}')

    return bet
Esempio n. 6
0
def get_bet_all(ctx: commands.Context,
                user: account.Account,
                user2: account.Account = None,
                history: bool = False) -> Union[list, int]:
    """Returns list of all Bets with user

    **Arguments**

    - `<ctx>` Context used to get information
    - `<user>` User who's bet you wish to get
    - `<user2>` User who you wanna search for as well
    - `<history>` Used to get either match history or active matches

    """
    logger.debug(f'bets.get_bet_all: {user}, {user2}, {history}')

    # Get all bets with user.id, check if bets is valid
    if history:
        bets = database_operation.get_bet_history_info_all(
            DbHandler.db_cnc, user.id)
    else:
        bets = database_operation.get_bet_info_all(DbHandler.db_cnc, user.id)
    if not bets:
        logger.error('bets is zero')
        return 0

    # Create bet list to return
    bet_list = []

    for bet in bets:
        # Get bettor and check if valid
        bettor = account.get_account_from_db(ctx, DbHandler.db_cnc, bet[3])
        logger.debug(f'bettor: {bettor}')
        if not bettor:
            logger.error('Unable to get bettor account')
            raise exception.UnableToRead(class_='Account', attribute='account')
        # Get bet_target and check if valid
        bet_target = account.get_account_from_db(ctx, DbHandler.db_cnc, bet[4])
        logger.debug(f'bet_target: {bet_target}')
        if not bet_target:
            logger.error('Unable to get bet_target account')
            raise exception.UnableToRead(class_='Account', attribute='account')
        # Get match and check if valid
        match = matches.get_match(ctx, bet[2], history)
        logger.debug(f'match: {match}')
        if not match:
            logger.error('Unable to get match')
            raise exception.UnableToRead(class_='Match', attribute='match')

        # Create match depending on if history is true or not
        if history:
            logger.debug('history is true')

            # Get winner and check if valid
            winner = account.get_account_from_db(ctx, DbHandler.db_cnc, bet[5])
            logger.debug(f'winner: {winner}')
            if not winner:
                logger.error('Unable to get winner account')
                raise exception.UnableToRead(class_='Account',
                                             attribute='account')

            append_bet = Bet(bet[0], bet[1], match, bettor, bet_target, winner,
                             bet[6], True)
        else:
            append_bet = Bet(bet[0], bet[1], match, bettor, bet_target)

        logger.debug(f'append_bet: {append_bet}')

        # Check if append_bet is filled
        if append_bet:
            bet_list.append(append_bet)

    # Check if list has been propagated, return 0 otherwise
    if not len(bet_list):
        logger.debug('bet_list length is zero')
        return 0

    # Return bets
    return bet_list
Esempio n. 7
0
 async def test(self, ctx: commands.Context):
     # Get match
     match = matches.get_match(ctx, 1, True)
     # Process bets
     bets.process_bets(ctx, match)
     pass
Esempio n. 8
0
    async def match_win(self, ctx: commands.Context, member: Union[discord.Member, str] = None):
        """Sets the winner of a marble match

        Examples:
            - `$winner @Sophia`
            - `$winner @Ness`

        **Arguments**

        - `<ctx>` The context used to send confirmations.
        - `<member>' Member to select as the winner.

        """
        logger.debug(f'match_win: {member}')
        # Checks if member is None, then sets member to ctx.author if true
        if member is None:
            member = ctx.author
        # Gets winner/match_id to process match and do integrity checks
        winner = acc.get_account(ctx, DbHandler.db_cnc, member)
        match_id = database_operation.find_match_by_player_id(DbHandler.db_cnc, winner.id)
        logger.debug(f'winner: {winner}, match_id: {match_id}')

        # Checks if they have an active match
        if not match_id:
            logger.debug('match_id is zero')
            await du.code_message(ctx, 'They have no active match', 3)
            return
        # Get match info from match_id
        try:
            match = ma.get_match(ctx, match_id)
            logger.debug(f'match: {match}')
        except commands.CommandError as e:
            logger.error(f'Unable to get match: {e}')
            await du.code_message(ctx, 'Unable to process match', 3)
            return

        # Set loser to other participant
        # Checks if participant1 is winner if true sets loser to participant2, or participant1 otherwise
        if winner == match.challenger:
            loser = match.recipient
        else:
            loser = match.challenger
        logger.debug(f'loser: {loser}')

        try:
            # Set match winner
            match.winner = winner
            # Add marbles to winner
            winner.marbles += match.amount * 2
            # Adds win/lose to winner/loser
            winner.wins += 1
            loser.loses += 1
        except commands.CommandError as e:
            logger.error(f'Unable to update player stats: {e}')
            await du.code_message(ctx, 'Was unable to update player stats please try again', 3)
            return

        logger.debug('Processed bets')
        # Creates a entry of match in match_history table, deletes from matches
        try:
            match.is_history = True
            match.match_time = datetime.utcnow()
            logger.debug('Updated match info')
            match.create_history()
            logger.debug('Created match_history for match')
            if bets.process_bets(ctx, match):
                logger.debug('Processed bets')
        except commands.CommandError as e:
            logger.error(f'Unable to create matches_history entry')
            await du.code_message(ctx, f'Failed to add match to history or to delete from matches: {match.id}', 3)
            return

        await du.code_message(ctx, f'{winner.nickname} is the winner, gaining a total of {match.amount} marbles!')
    async def bet(self, ctx: commands.Context,
                  bet_target: Union[discord.Member,
                                    str], match_id: int, marbles: int):
        """Places a bet on a active and not started match

        Example:
            - `$bet @Sophia 12 5`
            - `$bet @Ness 12 0`

        **Arguments**

        - `<winner>` The player you think will win the match.
        - `<match_id>` The id of the match you'd like to bet on
        - `<marbles>` Amount of marbles you'd like to bet on the match.
        """
        logger.debug(f'bet: {bet_target}, {match_id}, {marbles}')

        # Check if marbles is less than 0, return if not
        if marbles < 0:
            await du.code_message(ctx, 'Marbles cannot be negative')
            return

        # Get bettor/bet_target_id accounts
        bettor_acc = acc.get_account(ctx, DbHandler.db_cnc, ctx.author)
        bet_target_acc = acc.get_account(ctx, DbHandler.db_cnc, bet_target)
        logger.debug(f'bettor: {bettor_acc}, bet_target: {bet_target_acc}')

        # Check if marble count for bettor is greater than marbles
        if bettor_acc.marbles < marbles:
            await du.code_message(
                ctx, f'You do not have enough marbles for this bet\n'
                f'You have {bettor_acc.marbles} and need {marbles}')
            return

        # Get match_info and validate
        match_info = ma.get_match(
            ctx, match_id
        )  # database_operation.get_match_info_by_id(DbHandler.db_cnc, match_id)
        if not match_info:
            await du.code_message(ctx, 'Invalid match id')
            return

        # Check if match is started
        if match_info.active:
            await du.code_message(ctx,
                                  'Match has started and betting is closed')
            return

        # Check if match is accepted
        if not match_info.accepted:
            await du.code_message(
                ctx,
                'You can only bet on matches that both players have accepted')
            return

        # Check to make sure person placing bet is not in the match
        if match_info.challenger == bettor_acc or match_info.recipient == bettor_acc:
            await du.code_message(ctx, 'You cannot bet on matches you are in')
            return

        # Check to make sure bet_target_id is in match
        if match_info.challenger.id != bet_target_acc.id:
            if match_info.recipient.id != bet_target_acc.id:
                await du.code_message(ctx, 'Player is not in this match')
                return

        # Get bet_id if exists,
        bet_id = database_operation.find_bet(DbHandler.db_cnc, match_id,
                                             bettor_acc.id)

        # If bet exists, and marbles is zero delete bet
        if bet_id != 0:
            # Get bet with bet_id if it's not zero
            bet_info = bets.get_bet(ctx, bet_id)

            if marbles == 0:
                # Delete bet, and return marbles to bettor
                bet_info.delete_bet()
                bettor_acc.marbles += bet_info.amount
                await du.code_message(ctx, 'Bet deleted')
                return

            # Update bet
            # Add marbles back to user, then subtract the new amount
            bettor_acc.marbles += bet_info.amount
            bettor_acc.marbles -= marbles
            bet_info.bet_target = bet_target_acc
            bet_info.amount = marbles
            await du.code_message(ctx, 'Bet updated')
            return

        # Return if marbles is less than 1
        if marbles < 1:
            await du.code_message(ctx, 'Cannot be zero')
            return

        # Create bet
        bets.create_bet(ctx, None, marbles, match_info, bettor_acc,
                        bet_target_acc)
        # Take marbles
        bettor_acc.marbles = bettor_acc.marbles - marbles
        await du.code_message(ctx, 'Bet submitted')