File size: 14,479 Bytes
aad95f7
 
 
 
94166cb
47a6106
aad95f7
7917f65
 
94166cb
 
47a6106
 
 
 
 
 
 
29254f8
 
47a6106
23567d4
 
 
 
4d35aef
 
47a6106
94166cb
47a6106
 
 
 
 
 
 
5a642ea
47a6106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29254f8
 
47a6106
29254f8
 
 
 
87c1a2c
47a6106
 
 
 
 
 
 
94166cb
 
87c1a2c
 
 
47a6106
87c1a2c
47a6106
 
 
 
94166cb
 
47a6106
94166cb
47a6106
 
 
29254f8
 
 
 
47a6106
 
94166cb
 
47a6106
94166cb
47a6106
87c1a2c
94166cb
 
 
47a6106
7917f65
23567d4
a4b7e80
7917f65
47a6106
23567d4
7917f65
 
 
47a6106
7917f65
 
 
 
 
94166cb
7917f65
94166cb
7917f65
 
47a6106
a4b7e80
23567d4
 
47a6106
23567d4
 
47a6106
23567d4
 
 
 
 
 
 
 
47a6106
7917f65
 
5a642ea
7917f65
a4b7e80
47a6106
7917f65
47a6106
 
 
 
 
 
 
 
 
 
 
 
 
aad95f7
5a642ea
47a6106
 
5a642ea
 
47a6106
 
 
 
 
 
 
5a642ea
47a6106
5a642ea
47a6106
5a642ea
 
 
47a6106
5a642ea
47a6106
 
5a642ea
47a6106
5a642ea
47a6106
 
 
 
 
 
5a642ea
 
 
47a6106
 
 
 
5a642ea
47a6106
 
 
 
 
 
5a642ea
47a6106
 
 
5a642ea
47a6106
5a642ea
47a6106
 
 
 
5a642ea
47a6106
 
 
5a642ea
47a6106
5a642ea
 
47a6106
5a642ea
 
 
 
 
 
 
 
47a6106
 
 
 
 
5a642ea
 
47a6106
 
 
 
 
 
 
 
 
 
5a642ea
 
 
 
 
 
 
47a6106
5a642ea
 
 
 
 
 
47a6106
5a642ea
 
 
 
 
 
 
47a6106
5a642ea
 
 
 
47a6106
5a642ea
 
 
 
 
47a6106
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
import discord
from discord import app_commands
import aiohttp
import asyncio
from datetime import datetime, timezone, timedelta
from cash import user_cash  # Ensure you have a 'cash.py' module managing user_cash as a dictionary

user_bets = {}

API_KEY = "jE7yBJVRNAwdDesMgTzTXUUSx1It41Fq"

async def fetch_nhl_scores():
    today = datetime.now().strftime('%Y%m%d')
    url = f"https://api.foxsports.com/bifrost/v1/nhl/scoreboard/segment/{today}?apikey={API_KEY}"
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.json()

async def fetch_nfl_scores():
    current_year = datetime.now().year
    for week in range(1, 18):  # NFL regular season has 17 weeks
        url = f"https://api.foxsports.com/bifrost/v1/nfl/scoreboard/segment/{current_year}-{week}-1?apikey={API_KEY}"
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                data = await response.json()
                if data['sectionList'][0]['events'][0]['eventStatus'] == 2:
                    return data
    return None  # If no current week is found

class SportSelect(discord.ui.Select):
    def __init__(self):
        options = [
            discord.SelectOption(label="NHL", description="Bet on NHL games"),
            discord.SelectOption(label="NFL", description="Bet on NFL games")
        ]
        super().__init__(placeholder="Select a sport to bet on", min_values=1, max_values=1, options=options)

    async def callback(self, interaction: discord.Interaction):
        selected_sport = self.values[0]
        await interaction.response.edit_message(content=f"Selected Sport: {selected_sport}. Fetching games...", view=None)
        await asyncio.sleep(1)  # Brief pause for better UX

        if selected_sport == "NHL":
            scores = await fetch_nhl_scores()
            events = scores.get('sectionList', [])[0].get('events', [])
            upcoming_games = [game for game in events if game.get('eventStatus') == 2]
            if not upcoming_games:
                await interaction.followup.send("No NHL games available for betting today.", ephemeral=False)
                return
            view = GameSelect(upcoming_games, "NHL")
            await interaction.followup.send("Select a game to bet on:", view=view, ephemeral=False)
        elif selected_sport == "NFL":
            scores = await fetch_nfl_scores()
            if not scores:
                await interaction.followup.send("No NFL games available for betting this week.", ephemeral=False)
                return
            events = scores.get('sectionList', [])[0].get('events', [])
            upcoming_games = [game for game in events if game.get('eventStatus') == 2]
            if not upcoming_games:
                await interaction.followup.send("No NFL games available for betting this week.", ephemeral=False)
                return
            view = GameSelect(upcoming_games, "NFL")
            await interaction.followup.send("Select a game to bet on:", view=view, ephemeral=False)

class GameSelect(discord.ui.View):
    def __init__(self, games, league):
        super().__init__()
        self.league = league
        options = [
            discord.SelectOption(
                label=f"{game['lowerTeam']['longName']} vs {game['upperTeam']['longName']}",
                value=game['id'],
                description=f"Start time: <t:{int(datetime.fromisoformat(game['eventTime'].replace('Z', '+00:00')).timestamp())}:F>"
            ) for game in games
        ]
        self.games = {game['id']: game for game in games}
        self.add_item(GameOptionSelect(options, self.league, self.games))

class GameOptionSelect(discord.ui.Select):
    def __init__(self, options, league, games):
        super().__init__(placeholder="Select a game", min_values=1, max_values=1, options=options)
        self.league = league
        self.games = games

    async def callback(self, interaction: discord.Interaction):
        selected_game_id = self.values[0]
        game_data = self.games.get(selected_game_id)
        if not game_data:
            await interaction.response.send_message("Selected game data not found.", ephemeral=False)
            return
        await interaction.response.edit_message(content="Select a team to bet on:", view=None)
        await asyncio.sleep(1)  # Brief pause for better UX
        view = TeamSelect(game_data, self.league)
        await interaction.followup.send("Select a team to bet on:", view=view, ephemeral=False)

class TeamSelect(discord.ui.View):
    def __init__(self, game, league):
        super().__init__()
        self.league = league
        away_team = game['lowerTeam']
        home_team = game['upperTeam']
        options = [
            discord.SelectOption(label=away_team['longName'], value=away_team['name']),
            discord.SelectOption(label=home_team['longName'], value=home_team['name'])
        ]
        self.game = game
        self.add_item(TeamOptionSelect(options, league, game))

class TeamOptionSelect(discord.ui.Select):
    def __init__(self, options, league, game):
        super().__init__(placeholder="Select a team to bet on", min_values=1, max_values=1, options=options)
        self.league = league
        self.game = game

    async def callback(self, interaction: discord.Interaction):
        selected_team = self.values[0]
        await interaction.response.send_modal(BetModal(selected_team, interaction.user.id, self.game, self.league))

class BetModal(discord.ui.Modal, title="Place Your Bet"):
    bet_amount = discord.ui.TextInput(label="Bet Amount", placeholder="Enter bet amount", required=True)

    def __init__(self, team, user_id, game_data, league):
        super().__init__()
        self.team = team
        self.user_id = user_id
        self.game_data = game_data
        self.league = league

    async def on_submit(self, interaction: discord.Interaction):
        try:
            bet_amount = int(self.bet_amount.value)
            if bet_amount <= 0:
                raise ValueError("Bet amount must be greater than 0.")
            if bet_amount > user_cash.get(self.user_id, 0):
                raise ValueError("Insufficient balance. Please check your balance and try again.")

            user_cash[self.user_id] -= bet_amount
            await interaction.response.send_message(f"Bet placed on **{self.team}** for **${bet_amount}**.", ephemeral=False)

            user = await interaction.client.fetch_user(self.user_id)
            embed = discord.Embed(title="Bet Placed", color=0x787878)
            embed.add_field(name="League", value=self.league, inline=False)
            embed.add_field(name="Team", value=self.team, inline=False)
            embed.add_field(name="Amount", value=f"${bet_amount}", inline=False)
            game_description = f"{self.game_data['lowerTeam']['longName']} vs {self.game_data['upperTeam']['longName']}"
            start_time = self.game_data['eventTime']
            embed.add_field(name="Game", value=game_description, inline=False)
            embed.add_field(name="Start Time", value=f"<t:{int(datetime.fromisoformat(start_time.replace('Z', '+00:00')).timestamp())}:F>", inline=False)
            await user.send(embed=embed)

            if self.user_id not in user_bets:
                user_bets[self.user_id] = []
            user_bets[self.user_id].append({
                "league": self.league,
                "team": self.team,
                "amount": bet_amount,
                "game_data": self.game_data
            })

            asyncio.create_task(self.monitor_game(interaction, bet_amount))
        except ValueError as e:
            await interaction.response.send_message(str(e), ephemeral=False)

    async def monitor_game(self, interaction, bet_amount):
        game_start = datetime.fromisoformat(self.game_data['eventTime'].replace('Z', '+00:00'))
        event_id = self.game_data['id']
        fetch_scores = fetch_nhl_scores if self.league == "NHL" else fetch_nfl_scores

        sleep_duration = (game_start - datetime.now(timezone.utc)).total_seconds()
        if sleep_duration > 0:
            await asyncio.sleep(sleep_duration)

        user = await interaction.client.fetch_user(self.user_id)
        await user.send(f"Your team **{self.team}** has started playing!")

        previous_scores = {
            self.game_data['lowerTeam']['name']: self.game_data.get('lowerTeam', {}).get('score', 0),
            self.game_data['upperTeam']['name']: self.game_data.get('upperTeam', {}).get('score', 0)
        }

        while True:
            scores = await fetch_scores()
            game = None
            for section in scores.get('sectionList', []):
                for evt in section.get('events', []):
                    if evt['id'] == event_id:
                        game = evt
                        break
                if game:
                    break
            if not game:
                await asyncio.sleep(60)
                continue

            event_status = game.get('eventStatus', 2)
            current_scores = {
                game['lowerTeam']['name']: game['lowerTeam'].get('score', 0),
                game['upperTeam']['name']: game['upperTeam'].get('score', 0)
            }
            is_final = event_status == 3

            # Check for score updates
            for team, score in current_scores.items():
                if score > previous_scores.get(team, 0):
                    team_name = self.game_data['lowerTeam']['longName'] if team == self.game_data['lowerTeam']['name'] else self.game_data['upperTeam']['longName']
                    message = f"**{team_name}** SCORED! Current score: {current_scores[self.game_data['lowerTeam']['name']]} - {current_scores[self.game_data['upperTeam']['name']]}"
                    await user.send(message)

            previous_scores = current_scores.copy()

            if is_final:
                away_score = current_scores.get(self.game_data['lowerTeam']['name'], 0)
                home_score = current_scores.get(self.game_data['upperTeam']['name'], 0)
                winner = self.game_data['lowerTeam']['name'] if away_score > home_score else self.game_data['upperTeam']['name']

                if winner == self.team:
                    winnings = bet_amount * 2
                    user_cash[self.user_id] += winnings
                    await user.send(f"πŸŽ‰ **Congratulations!** Your team **{self.team}** won! You won **${winnings}**!")
                else:
                    await user.send(f"😞 **Sorry!** Your team **{self.team}** lost. Better luck next time!")

                # Remove the completed bet
                user_bets[self.user_id] = [bet for bet in user_bets[self.user_id] if not (bet['league'] == self.league and bet['team'] == self.team and bet['game_data']['id'] == event_id)]
                break

            await asyncio.sleep(60)  # Check every minute

class SportBetView(discord.ui.View):
    def __init__(self):
        super().__init__()
        self.add_item(SportSelect())

    @discord.ui.button(label="View Bets", style=discord.ButtonStyle.secondary)
    async def view_bets(self, interaction: discord.Interaction, button: discord.ui.Button):
        await show_current_bets(interaction)

async def show_current_bets(interaction: discord.Interaction):
    user_id = interaction.user.id
    if user_id not in user_bets or not user_bets[user_id]:
        await interaction.response.send_message("You have no active bets.", ephemeral=False)
        return

    embed = discord.Embed(title="Your Current Bets", color=0x787878)
    for i, bet in enumerate(user_bets[user_id], 1):
        league = bet['league']
        team = bet['team']
        amount = bet['amount']
        game = bet['game_data']
        game_description = f"{game['lowerTeam']['longName']} vs {game['upperTeam']['longName']}"
        start_time = game['eventTime']
        score = f"{game['lowerTeam'].get('score', 'N/A')} - {game['upperTeam'].get('score', 'N/A')}"
        status = "Final" if game.get('upperTeam', {}).get('score') is not None else f"Starts <t:{int(datetime.fromisoformat(start_time.replace('Z', '+00:00')).timestamp())}:R>"

        embed.add_field(
            name=f"Bet {i}: {league}",
            value=(
                f"**Team:** {team}\n"
                f"**Amount:** ${amount}\n"
                f"**Game:** {game_description}\n"
                f"**Status:** {status}\n"
                f"**Current Score:** {score}\n"
                f"**Start Time:** <t:{int(datetime.fromisoformat(start_time.replace('Z', '+00:00')).timestamp())}:F>"
            ),
            inline=False
        )

    view = discord.ui.View()
    cancel_select = discord.ui.Select(
        placeholder="Select a bet to cancel",
        min_values=1,
        max_values=1,
        options=[
            discord.SelectOption(label=f"Bet {i}", value=str(i-1)) for i in range(1, len(user_bets[user_id]) + 1)
        ]
    )
    view.add_item(cancel_select)

    async def cancel_callback(interaction_cancel: discord.Interaction):
        if interaction_cancel.user.id != user_id:
            await interaction_cancel.response.send_message("You cannot cancel other users' bets.", ephemeral=False)
            return

        bet_index = int(cancel_select.values[0])
        cancelled_bet = user_bets[user_id][bet_index]
        start_time = datetime.fromisoformat(cancelled_bet['game_data']['eventTime'].replace('Z', '+00:00'))

        if datetime.now(timezone.utc) >= start_time:
            await interaction_cancel.response.send_message("You cannot cancel your bet as the game has already started.", ephemeral=False)
            return

        user_cash[user_id] += cancelled_bet['amount']
        user_bets[user_id].pop(bet_index)
        await interaction_cancel.response.send_message(f"Bet cancelled. **${cancelled_bet['amount']}** has been refunded.", ephemeral=False)
        if not user_bets[user_id]:
            del user_bets[user_id]

    cancel_select.callback = cancel_callback

    await interaction.response.send_message(embed=embed, view=view, ephemeral=False)

@app_commands.command(name="sportbet", description="Bet on sports games")
async def sportbet(interaction: discord.Interaction):
    view = SportBetView()
    await interaction.response.send_message("Select a sport to bet on:", view=view, ephemeral=False)