Glorified / app.py
araeyn's picture
added uuid generation and token creation
3116fdf
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)