import asyncio import json import secrets import uuid from datetime import datetime from pathlib import Path from argon2 import PasswordHasher from fastapi import FastAPI, Form, HTTPException, WebSocket, WebSocketDisconnect from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse # Constants USERS_FILE = Path("users.json") GLARES_FILE = Path("glares.json") GLARE_CAP = 1000 BASE_RATE = 1 # max glr/sec TIME_FORMAT = "%Y-%m-%dT%H:%M:%S" # App setup app = FastAPI() ph = PasswordHasher() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"] ) # ---------------------- Helper Functions ---------------------- # def secure_crash_point(): r = secrets.randbelow(10**6) / 10**6 if r == 1.0: r = 0.999999 return round(max(1.0, 1.0 / (0.99 * (1.0 - r))), 2) def secure_uniform(a, b): # Generates a float in [a, b) using secrets scale = secrets.randbelow(10**6) / 10**6 # 0.000000 to 0.999999 return a + (b - a) * scale def weighted_choice(elements, probabilities): # Ensure probabilities sum to 1 total = sum(probabilities) if not abs(total - 1.0) < 1e-8: raise ValueError("Probabilities must sum to 1.") # Compute cumulative probabilities cumulative = [] cumsum = 0.0 for p in probabilities: cumsum += p cumulative.append(cumsum) # Generate a random float in [0, 1) r = secrets.randbelow(10**8) / 10**8 # Find the element corresponding to r for i, cp in enumerate(cumulative): if r < cp: return elements[i] return elements[-1] # fallback in case of rounding # Example usage: elements = ["apple", "banana", "cherry"] probabilities = [0.2, 0.5, 0.3] result = weighted_choice(elements, probabilities) print(result) # ---------------------- Storage ---------------------- # def load_json(path: Path): if not path.exists(): return {} with open(path, "r") as f: return json.load(f) def save_json(path: Path, data): with open(path, "w") as f: json.dump(data, f, indent=2) # ---------------------- Auth ---------------------- # def register_user(username: str, password: str): users = load_json(USERS_FILE) if username in users: raise HTTPException(status_code=400, detail="User already exists") hashed = ph.hash(password) user_id = str(uuid.uuid4()) token = secrets.token_hex(32) users[username] = { "userId": user_id, "password": hashed, "token": token, } save_json(USERS_FILE, users) return token def verify_token(token: str): users = load_json(USERS_FILE) for username, user in users.items(): if user.get("token") == token: return username return None def verify_user_password(username: str, password: str): users = load_json(USERS_FILE) if username not in users: return False try: ph.verify(users[username]["password"], password) return True except Exception as e: print(f"Verification error: {e}") return False def get_user_token(username: str): users = load_json(USERS_FILE) user = users.get(username) if user: return user.get("token") return None # ---------------------- Glares System ---------------------- # def get_updated_glares(username: str): glares = load_json(GLARES_FILE) now = datetime.utcnow() if username not in glares: glares[username] = [0, now.strftime(TIME_FORMAT)] save_json(GLARES_FILE, glares) return 0 current, last_time = glares[username] last = datetime.strptime(last_time, TIME_FORMAT) delta = (now - last).total_seconds() if current >= GLARE_CAP: return current earn_rate = BASE_RATE * (1 - current / GLARE_CAP) earned = delta * earn_rate new_total = min(current + earned, GLARE_CAP) glares[username] = [int(new_total), now.strftime(TIME_FORMAT)] save_json(GLARES_FILE, glares) return new_total def update_user_glares(username: str, earnings: float): glares = load_json(GLARES_FILE) now = datetime.utcnow().strftime(TIME_FORMAT) glares[username] = [glares[username][0] + earnings, now] save_json(GLARES_FILE, glares) # ---------------------- Routes ---------------------- # @app.post("/register") def register(username: str = Form(...), password: str = Form(...)): token = register_user(username, password) return JSONResponse( content={"message": "User registered successfully", "token": token} ) @app.post("/login") def login(username: str = Form(...), password: str = Form(...)): if verify_user_password(username, password): token = get_user_token(username) return JSONResponse(content={"message": "Login successful", "token": token}) raise HTTPException(status_code=401, detail="Invalid credentials") @app.get("/glares") def get_glares(token: str): username = verify_token(token) if not username: raise HTTPException(status_code=401, detail="Invalid token") current = get_updated_glares(username) return {"username": username, "glares": current} # ---------------------- Coin Flip ---------------------- # @app.websocket("/ws/coinflip") async def coinflip(websocket: WebSocket): """Edge: 1%""" await websocket.accept() try: # First message must be auth auth = await websocket.receive_json() token = auth.get("token") username = verify_token(token) if not username: await websocket.send_json({"error": "Invalid token"}) await websocket.close() return # Get updated balance on connect balance = get_updated_glares(username) await websocket.send_json({"message": f"Welcome {username}", "glares": balance}) while True: data = await websocket.receive_json() guess = data.get("guess") bet = data.get("bet", 0) if not isinstance(bet, int): await websocket.send_json({"error": "Invalid bet"}) continue if guess not in ["heads", "tails"] or bet <= 0: await websocket.send_json({"error": "Invalid bet or guess"}) continue current = get_updated_glares(username) if current < bet: await websocket.send_json({"error": "Insufficient glares"}) continue result = secrets.choice(["heads", "tails"]) win = result == guess if win: # Take 2% commission on wins commission = bet * 0.02 net_win = bet - commission update_user_glares(username, net_win) earnings = net_win else: commission = 0 update_user_glares(username, -bet) earnings = -bet await websocket.send_json( { "guess": guess, "result": result, "outcome": "win" if win else "lose", "earnings": earnings, "commission": commission if win else 0, } ) except WebSocketDisconnect: print("Disconnected") except Exception as e: await websocket.send_json({"error": str(e)}) await websocket.close() # ---------------------- Roulette ---------------------- # @app.websocket("/ws/roulette") async def roulette(websocket: WebSocket): await websocket.accept() try: # First message must be auth auth = await websocket.receive_json() token = auth.get("token") username = verify_token(token) if not username: await websocket.send_json({"error": "Invalid token"}) await websocket.close() return # Get updated balance on connect balance = get_updated_glares(username) await websocket.send_json({"message": f"Welcome {username}", "glares": balance}) while True: data = await websocket.receive_json() bet = data.get("bet") total_bet = sum(int(v) for v in bet.values()) for n in bet.values(): if not isinstance(n, int) or n < 0: await websocket.send_json({"error": "Invalid bet"}) continue balance = get_updated_glares(username) if total_bet > balance: await websocket.send_json({"error": "Insufficient glares"}) continue if total_bet <= 0: await websocket.send_json({"error": "Invalid bet"}) continue earnings = 0 chosen = secrets.choice(range(37)) if chosen == 0: color = "green" elif chosen in [ 1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, ]: color = "red" else: color = "black" even_odd = "even" if chosen % 2 == 0 else "odd" if isinstance(bet, dict): for number in range(37): if str(number) in bet: if ( not isinstance(bet[str(number)], int) or bet[str(number)] <= 0 ): await websocket.send_json({"error": "Invalid bet"}) continue if number == chosen: earnings += int(bet[str(number)]) * 35 else: earnings -= int(bet[str(number)]) for col in ["red", "black"]: if col in bet: if not isinstance(bet[col], int) or bet[col] <= 0: await websocket.send_json({"error": "Invalid bet"}) continue if color == col: earnings += int(bet[col]) else: earnings -= int(bet[col]) for eo in ["even", "odd"]: if eo in bet: if not isinstance(bet[even_odd], int) or bet[even_odd] <= 0: await websocket.send_json({"error": "Invalid bet"}) continue if eo == even_odd: earnings += int(bet[eo]) else: earnings -= int(bet[eo]) for dozen in ["d1", "d2", "d3"]: if dozen in bet: if not isinstance(bet[dozen], int) or bet[dozen] <= 0: await websocket.send_json({"error": "Invalid bet"}) continue if chosen in range(1, 13) and dozen == "d1": earnings += int(bet[dozen]) * 2 elif chosen in range(13, 25) and dozen == "d2": earnings += int(bet[dozen]) * 2 elif chosen in range(25, 37) and dozen == "d3": earnings += int(bet[dozen]) * 2 else: earnings -= int(bet[dozen]) for column in ["c1", "c2", "c3"]: if column in bet: if not isinstance(bet[column], int) or bet[column] <= 0: await websocket.send_json({"error": "Invalid bet"}) continue if chosen in range(1, 37): if column == "c1" and chosen % 3 == 1: earnings += int(bet[column]) * 2 elif column == "c2" and chosen % 3 == 2: earnings += int(bet[column]) * 2 elif column == "c3" and chosen % 3 == 0: earnings += int(bet[column]) * 2 else: earnings -= int(bet[column]) for half in ["h1", "h2"]: if half in bet: if not isinstance(bet[half], int) or bet[half] <= 0: await websocket.send_json({"error": "Invalid bet"}) continue if chosen in range(1, 19) and half == "h1": earnings += int(bet[half]) elif chosen in range(19, 37) and half == "h2": earnings += int(bet[half]) else: earnings -= int(bet[half]) for street in [ "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "s12", ]: if street in bet: if not isinstance(bet[street], int) or bet[street] <= 0: await websocket.send_json({"error": "Invalid bet"}) continue if street == f"s{(chosen - 1) // 3 + 1}": earnings += int(bet[street]) * 11 else: earnings -= int(bet[street]) update_user_glares(username, earnings) await websocket.send_json( { "chosen": chosen, "color": color, "even_odd": even_odd, "earnings": earnings, } ) print( f"Bet details: chosen={chosen}, color={color}, even_odd={even_odd}, earnings={earnings}" ) else: await websocket.send_json({"error": "Invalid bet"}) except WebSocketDisconnect: print("Disconnected") except Exception as e: await websocket.send_json({"error": str(e)}) await websocket.close() # ---------------------- Spinner ---------------------- # @app.websocket("/ws/spinner") async def spinner(websocket: WebSocket): """Edge: 0.988%""" await websocket.accept() try: # First message must be auth auth = await websocket.receive_json() token = auth.get("token") username = verify_token(token) if not username: await websocket.send_json({"error": "Invalid token"}) await websocket.close() return # Get updated balance on connect balance = get_updated_glares(username) await websocket.send_json({"message": f"Welcome {username}", "glares": balance}) while True: data = await websocket.receive_json() bet = data.get("bet") probs = [0.3333, 0.4291, 0.2376] mults = [0.0, 1.2, 2.0] multiplier = weighted_choice(mults, probs) print(type(bet), bet) if not isinstance(bet, int) or bet <= 0: await websocket.send_json({"error": "Invalid bet"}) continue balance = get_updated_glares(username) if bet > balance: await websocket.send_json({"error": "Insufficient glares"}) continue earnings = multiplier * bet - bet update_user_glares(username, earnings) await websocket.send_json({"multiplier": multiplier, "earnings": earnings}) except WebSocketDisconnect: print("Disconnected") except Exception as e: await websocket.send_json({"error": str(e)}) await websocket.close() # ---------------------- Crash ---------------------- # @app.websocket("/ws/crash") async def crash(websocket: WebSocket): """Edge: 1%""" await websocket.accept() try: # First message must be auth auth = await websocket.receive_json() token = auth.get("token") username = verify_token(token) if not username: await websocket.send_json({"error": "Invalid token"}) await websocket.close() return # Get updated balance on connect balance = get_updated_glares(username) await websocket.send_json({"message": f"Welcome {username}", "glares": balance}) while True: data = await websocket.receive_json() bet = data.get("bet") if not isinstance(bet, int) or bet <= 0: await websocket.send_json({"error": "Invalid bet"}) continue balance = get_updated_glares(username) if bet > balance: await websocket.send_json({"error": "Insufficient glares"}) continue update_user_glares(username, -bet) crash_point = round(min(secure_crash_point(), 100), 2) multiplier = 1.0 cashout = 0.0 crashed = False async def send_updates(): nonlocal multiplier, crashed while not crashed: await asyncio.sleep(0.01) # 10ms multiplier += multiplier * 0.00075 await websocket.send_json({"multiplier": round(multiplier, 2)}) if multiplier >= crash_point: crashed = True await websocket.send_json({"crash": crash_point}) async def receive_cashout(): nonlocal cashout, crashed while not crashed: try: msg = await asyncio.wait_for( websocket.receive_json(), timeout=0.01 ) if msg.get("action") == "cashout": cashout = multiplier crashed = True await websocket.send_json({"cashed_out": round(cashout, 2)}) except asyncio.TimeoutError: continue await asyncio.gather(send_updates(), receive_cashout()) if cashout: earned = cashout * bet update_user_glares(username, earned) await websocket.send_json( { "message": f"Cashout successful! Multiplier: {round(cashout, 2)}", "earnings": round(earned, 2), } ) elif crashed: await websocket.send_json( { "message": f"Game crashed at {round(crash_point, 2)}x! You lost your bet.", "earnings": 0, } ) except WebSocketDisconnect: print("Disconnected") except Exception as e: await websocket.send_json({"error": str(e)}) await websocket.close() # ---------------------- Mines ---------------------- # @app.websocket("/ws/mines") async def mines(websocket: WebSocket): """Edge: 1%""" await websocket.accept() try: # First message must be auth auth = await websocket.receive_json() token = auth.get("token") username = verify_token(token) if not username: await websocket.send_json({"error": "Invalid token"}) await websocket.close() return # Get updated balance on connect balance = get_updated_glares(username) await websocket.send_json({"message": f"Welcome {username}", "glares": balance}) while True: data = await websocket.receive_json() bet = data.get("bet") mines = data.get("mines", 1) if not isinstance(bet, int) or bet <= 0: await websocket.send_json({"error": "Invalid bet"}) continue balance = get_updated_glares(username) if bet > balance: await websocket.send_json({"error": "Insufficient glares"}) continue update_user_glares(username, -bet) if mines < 1 or mines > 24 or not isinstance(mines, int): await websocket.send_json({"error": "Invalid number of mines"}) continue positions = secrets.SystemRandom().sample(range(0, 25), mines) safe_positions = set(range(0, 25)) - set(positions) revealed = set() multiplier = 1.0 while True: data = await websocket.receive_json() action = data.get("action") if action == "reveal": position = data.get("position") if not isinstance(position, int) or position < 0 or position > 24: await websocket.send_json({"error": "Invalid position"}) continue if position in revealed: await websocket.send_json( {"error": "Position already revealed"} ) continue if position not in safe_positions: multiplier = 0 break revealed.add(position) safe_positions.remove(position) multiplier += (25 / len(safe_positions) - 1) * 0.99 await websocket.send_json( { "multiplier": round(multiplier, 2), "revealed": list(revealed), } ) elif action == "cashout": break else: await websocket.send_json({"error": "Invalid action"}) continue earned = bet * multiplier update_user_glares(username, earned) await websocket.send_json( { "multiplier": round(multiplier, 2), "earnings": round(earned, 2), "safe_positions": list(safe_positions), } ) except WebSocketDisconnect: print("Disconnected") except Exception as e: await websocket.send_json({"error": str(e)}) await websocket.close() # ---------------------- Tower ---------------------- # @app.websocket("/ws/tower") async def tower(websocket: WebSocket): """Edge: 1%""" await websocket.accept() try: # First message must be auth auth = await websocket.receive_json() token = auth.get("token") username = verify_token(token) if not username: await websocket.send_json({"error": "Invalid token"}) await websocket.close() return # Get updated balance on connect balance = get_updated_glares(username) await websocket.send_json({"message": f"Welcome {username}", "glares": balance}) while True: data = await websocket.receive_json() bet = data.get("bet") # difficulty = data.get("difficulty", 1) difficulty = 1 if difficulty not in [1, 2, 3]: await websocket.send_json({"error": "Invalid difficulty"}) continue if not isinstance(bet, int) or bet <= 0: await websocket.send_json({"error": "Invalid bet"}) continue balance = get_updated_glares(username) if bet > balance: await websocket.send_json({"error": "Insufficient glares"}) continue update_user_glares(username, -bet) safe_positions = list() if difficulty == 1: safe_positions = [secrets.randbelow(4) for _ in range(8)] level = 0 multiplier = 1.0 while True: data = await websocket.receive_json() action = data.get("action") if action == "reveal": position = data.get("position") if difficulty == 1: if position not in [0, 1, 2, 3]: await websocket.send_json({"error": "Invalid position"}) continue if position == safe_positions[level]: if level < 8: level += 1 multiplier += 3 / 4 * 0.99 safe_positions.remove(position) await websocket.send_json( { "level": level, "multiplier": round(multiplier, 2), } ) else: multiplier += 3 / 4 * 0.99 await websocket.send_json( { "level": level, "multiplier": round(multiplier, 2), "completed": True, } ) break else: multiplier = 0 break elif action == "cashout": break else: await websocket.send_json({"error": "Invalid action"}) continue earned = bet * multiplier update_user_glares(username, earned) await websocket.send_json( { "multiplier": round(multiplier, 2), "earnings": round(earned, 2), "safe_positions": safe_positions, } ) except WebSocketDisconnect: print("Disconnected") except Exception as e: await websocket.send_json({"error": str(e)}) await websocket.close() # ---------------------- Blackjack ---------------------- # @app.websocket("/ws/blackjack") async def blackjack(websocket: WebSocket): """Edge: 1%""" await websocket.accept() try: # First message must be auth auth = await websocket.receive_json() token = auth.get("token") username = verify_token(token) if not username: await websocket.send_json({"error": "Invalid token"}) await websocket.close() return # Get updated balance on connect balance = get_updated_glares(username) await websocket.send_json({"message": f"Welcome {username}", "glares": balance}) while True: data = await websocket.receive_json() bet = data.get("bet") update_user_glares(username, -bet) if not isinstance(bet, int) or bet <= 0: await websocket.send_json({"error": "Invalid bet"}) continue balance = get_updated_glares(username) if bet > balance: await websocket.send_json({"error": "Insufficient glares"}) continue update_user_glares(username, -bet) deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11] * 4 secrets.SystemRandom().shuffle(deck) done = False earnings = 0 while True: player_hand = [deck.pop(), deck.pop()] dealer_hand = [deck.pop(), deck.pop()] player_total = sum(player_hand) dealer_total = sum(dealer_hand) if player_total == 21: done = True earnings = bet * 1.5 + bet break while True: action = await websocket.receive_json() if action.get("action") == "hit": player_hand.append(deck.pop()) player_total = sum(player_hand) if player_total > 21: done = True earnings = 0 break await websocket.send_json( {"player_hand": player_hand, "player_total": player_total} ) elif action.get("action") == "stand": break else: await websocket.send_json({"error": "Invalid action"}) continue if done: break while dealer_total < 17: dealer_hand.append(deck.pop()) dealer_total = sum(dealer_hand) if dealer_total > 21: done = True earnings = bet * 1 + bet break if done: break if player_total > dealer_total: earnings = bet * 1 + bet done = True elif player_total < dealer_total: earnings = 0 done = True else: earnings = bet done = True await websocket.send_json( { "player_hand": player_hand, "player_total": player_total, "dealer_hand": dealer_hand, "dealer_total": dealer_total, "earnings": earnings, } ) except WebSocketDisconnect: print("Disconnected") except Exception as e: await websocket.send_json({"error": str(e)}) await websocket.close() # ---------------------- Hi-Lo ---------------------- # @app.websocket("/ws/hilo") async def hilo(websocket: WebSocket): """Edge: 1%""" await websocket.accept() try: # First message must be auth auth = await websocket.receive_json() token = auth.get("token") username = verify_token(token) if not username: await websocket.send_json({"error": "Invalid token"}) await websocket.close() return # Get updated balance on connect balance = get_updated_glares(username) await websocket.send_json({"message": f"Welcome {username}", "glares": balance}) while True: data = await websocket.receive_json() bet = data.get("bet") if not isinstance(bet, int) or bet <= 0: await websocket.send_json({"error": "Invalid bet"}) continue balance = get_updated_glares(username) if bet > balance: await websocket.send_json({"error": "Insufficient glares"}) continue update_user_glares(username, -bet) cards = list(range(1, 53)) secrets.SystemRandom().shuffle(cards) card = cards.pop() card_value = card % 13 if card_value == 0: card_value = 13 multiplier = 1.0 while True: action = await websocket.receive_json() if action.get("action") == "higher": next_card = cards.pop() next_card_value = next_card % 13 if next_card_value == 0: next_card_value = 13 if next_card_value == card_value == 1: # Ace multiplier = 0 break if next_card_value >= card_value: multiplier += (14 - card_value) / 12 * 0.99 else: multiplier = 0 break elif action.get("action") == "lower": next_card = cards.pop() next_card_value = next_card % 13 if next_card_value == card_value == 0: # King multiplier = 0 break if next_card_value <= card_value: multiplier += (card_value) / 12 * 0.99 else: multiplier = 0 break elif action.get("action") == "skip": next_card = cards.pop() elif action.get("action") == "cashout": break else: await websocket.send_json({"error": "Invalid action"}) continue earnings = bet * multiplier update_user_glares(username, earnings) await websocket.send_json( {"earnings": round(earnings, 2), "multiplier": round(multiplier, 2)} ) except WebSocketDisconnect: print("Disconnected") except Exception as e: await websocket.send_json({"error": str(e)}) await websocket.close() # ---------------------- Main ---------------------- # if __name__ == "__main__": import uvicorn uvicorn.run("app:app", host="0.0.0.0", port=7860, reload=False)