-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
278 lines (216 loc) · 7.89 KB
/
Copy pathapp.py
File metadata and controls
278 lines (216 loc) · 7.89 KB
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
from flask import Flask, render_template, request, jsonify, session, redirect
from flask_socketio import SocketIO, emit
import httpx
import numpy as np
import eventlet
import sqlite3
from dotenv import load_dotenv
import os
# Load environment variables
load_dotenv()
CLIENT_ID = os.getenv("DISCORD_CLIENT_ID")
CLIENT_SECRET = os.getenv("DISCORD_CLIENT_SECRET")
REDIRECT_URI = os.getenv("DISCORD_REDIRECT_URI")
app = Flask(__name__)
app.config.update(
SECRET_KEY=os.getenv("SECRET_KEY"),
SESSION_COOKIE_SAMESITE='Lax',
SESSION_COOKIE_SECURE=False
)
socketio = SocketIO(app, cors_allowed_origins="*")
MULT_SPEED = 0.006
# Game and user state
current_multiplier = 1.0
round_active = False
user_bets = {}
game_running = False
# Determine DB path (Koyeb volume or local)
if os.path.exists("/mnt/storage"):
DB_PATH = "/mnt/storage/players.db"
else:
DB_PATH = os.path.join(os.path.dirname(__file__), "players.db")
def get_db_connection():
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn
if not os.path.exists(DB_PATH):
print("Creating new database at", DB_PATH)
conn = sqlite3.connect(DB_PATH)
conn.execute("""
CREATE TABLE IF NOT EXISTS players (
discord_id TEXT PRIMARY KEY,
username TEXT,
balance INTEGER DEFAULT 0,
has_bet BOOLEAN DEFAULT 0
)
""")
conn.commit()
conn.close()
def update_balance(discord_id, amount):
conn = get_db_connection()
conn.execute("UPDATE players SET balance = balance + ? WHERE discord_id = ?", (amount, discord_id))
conn.commit()
conn.close()
def register_player(discord_id, username):
conn = get_db_connection()
try:
conn.execute("INSERT INTO players (discord_id, username) VALUES (?, ?)", (discord_id, username))
conn.commit()
except sqlite3.IntegrityError:
pass
finally:
conn.close()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/crash')
def crash_page():
return render_template('crash.html')
@app.route('/login')
def login():
return redirect(
f"https://discord.com/api/oauth2/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=identify"
)
@app.route('/callback')
def callback():
code = request.args.get('code')
if not code:
return "Missing code", 400
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI,
'scope': 'identify'
}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
try:
token_res = httpx.post('https://discord.com/api/oauth2/token', data=data, headers=headers)
token_res.raise_for_status()
token = token_res.json().get('access_token')
except Exception:
return "Token exchange failed", 400
if not token:
return "Failed to get token", 400
user_res = httpx.get('https://discord.com/api/users/@me', headers={'Authorization': f'Bearer {token}'})
if user_res.status_code != 200:
return "Failed to fetch user info", 400
user = user_res.json()
session['discord_id'] = user['id']
session['username'] = user['username']
register_player(user['id'], user['username'])
return redirect('/')
@app.route('/current_user')
def current_user():
if 'discord_id' not in session:
return jsonify({'logged_in': False})
return jsonify({
'logged_in': True,
'discord_id': session['discord_id'],
'username': session['username']
})
@app.route('/get_user/<discord_id>')
def get_user(discord_id):
conn = get_db_connection()
cur = conn.execute("SELECT username, balance, has_bet FROM players WHERE discord_id = ?", (discord_id,))
row = cur.fetchone()
conn.close()
if row:
return jsonify({'username': row['username'], 'balance': row['balance'], 'has_bet': row['has_bet']})
return jsonify({'error': 'User not found'}), 404
@socketio.on('place_bet')
def handle_place_bet():
user_id = request.sid
if round_active:
emit('bet_rejected', {'reason': "Round already started."})
return
if 'discord_id' not in session:
emit('bet_rejected', {'reason': "Not logged in."})
return
discord_id = session['discord_id']
conn = get_db_connection()
cur = conn.execute("SELECT username FROM players WHERE discord_id = ?", (discord_id,))
row = cur.fetchone()
conn.close()
if not row:
emit('bet_rejected', {'reason': "User not found in DB."})
return
username = row['username']
bet_amount = 1000
conn = get_db_connection()
cur = conn.execute("SELECT balance FROM players WHERE discord_id = ?", (discord_id,))
row = cur.fetchone()
conn.close()
if not row or row['balance'] < bet_amount:
emit('bet_rejected', {'reason': "Insufficient balance or user not found."})
return
update_balance(discord_id, -bet_amount)
conn = get_db_connection()
conn.execute("UPDATE players SET has_bet = 1 WHERE discord_id = ?", (discord_id,))
conn.commit()
conn.close()
user_bets[user_id] = {
'bet': True,
'cashed_out': False,
'mult': None,
'username': username,
'discord_id': discord_id,
'bet_amount': bet_amount
}
conn = get_db_connection()
cur = conn.execute("SELECT balance FROM players WHERE discord_id = ?", (discord_id,))
new_balance = cur.fetchone()['balance']
conn.close()
emit('bet_accepted')
socketio.emit('user_bet', {'username': username, 'balance': new_balance})
@socketio.on('stop_bet')
def handle_stop_bet():
user_id = request.sid
if user_id not in user_bets or not user_bets[user_id]['bet'] or user_bets[user_id]['cashed_out']:
return
user_bets[user_id]['cashed_out'] = True
user_bets[user_id]['mult'] = round(current_multiplier, 2)
discord_id = user_bets[user_id]['discord_id']
username = user_bets[user_id]['username']
bet_amount = user_bets[user_id]['bet_amount']
payout = round(bet_amount * current_multiplier, 2)
update_balance(discord_id, payout)
conn = get_db_connection()
cur = conn.execute("SELECT balance FROM players WHERE discord_id = ?", (discord_id,))
new_balance = cur.fetchone()['balance']
conn.close()
socketio.emit('user_cashout', {
'username': username,
'multiplier': round(current_multiplier, 2),
'balance': new_balance
})
def game_loop():
global current_multiplier, round_active
while True:
round_active = False
for seconds_left in range(10, 0, -1):
socketio.emit('countdown', {'time': seconds_left})
eventlet.sleep(1)
round_active = True
socketio.emit('start_round')
multiplier = 1.0
instant_crash = np.random.randint(1, 101)
crash_point = 0 if instant_crash <= 4 else np.random.exponential(2.5) + 1
while multiplier < crash_point:
current_multiplier = multiplier
socketio.emit('multiplier_update', {'multiplier': round(multiplier, 2)})
eventlet.sleep(0.04)
multiplier += multiplier * MULT_SPEED
round_active = False
socketio.emit('crash', {'crash_point': round(crash_point, 2)})
conn = get_db_connection()
conn.execute("UPDATE players SET has_bet = 0")
conn.commit()
conn.close()
eventlet.sleep(3)
if not game_running:
game_running = True
eventlet.spawn(game_loop)
if __name__ == '__main__':
socketio.run(app, host="0.0.0.0", port=5000, debug=False, use_reloader=False)