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}')
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}.')
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')
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.')
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
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
async def test(self, ctx: commands.Context): # Get match match = matches.get_match(ctx, 1, True) # Process bets bets.process_bets(ctx, match) pass
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')