Refator eco code. Split into modules
This commit is contained in:
79
core/economy/jail.py
Normal file
79
core/economy/jail.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Jail, jailbreak and bail."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from datetime import timedelta
|
||||
|
||||
from .store import (
|
||||
_commit, _is_jailed, _locked_by, _now, _txn, get_all_users_raw, get_user,
|
||||
)
|
||||
|
||||
|
||||
@_locked_by(0)
|
||||
async def do_spam_jail(user_id: int) -> None:
|
||||
"""Jail a user for 30 minutes due to suspected automated command spam."""
|
||||
user = await get_user(user_id)
|
||||
user["jailed_until"] = (_now() + timedelta(minutes=30)).isoformat()
|
||||
user["jailbreak_used"] = False
|
||||
user["times_jailed"] = user.get("times_jailed", 0) + 1
|
||||
await _commit(user_id, user)
|
||||
_txn("SPAM_JAIL", user=user_id, until=user["jailed_until"])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# /jailbreak (Monopoly-style dice rolls)
|
||||
# ---------------------------------------------------------------------------
|
||||
@_locked_by(0)
|
||||
async def set_jailbreak_used(user_id: int) -> None:
|
||||
"""Mark that the user has consumed their dice attempt for this jail sentence."""
|
||||
user = await get_user(user_id)
|
||||
user["jailbreak_used"] = True
|
||||
await _commit(user_id, user)
|
||||
|
||||
|
||||
@_locked_by(0)
|
||||
async def do_jail_free(user_id: int) -> dict:
|
||||
"""Remove jail status after rolling doubles."""
|
||||
user = await get_user(user_id)
|
||||
user["jailed_until"] = None
|
||||
user["jailbreak_used"] = False
|
||||
await _commit(user_id, user)
|
||||
_txn("JAIL_FREE", user=user_id, method="doubles")
|
||||
return {"ok": True, "balance": user["balance"]}
|
||||
|
||||
|
||||
MIN_BAIL = 350
|
||||
|
||||
@_locked_by(0)
|
||||
async def do_bail(user_id: int) -> dict:
|
||||
"""Charge bail fine after exhausting jailbreak rolls and free the user.
|
||||
Fine = 20-30% of current balance, floored at 350. If balance < 350, stay jailed."""
|
||||
user = await get_user(user_id)
|
||||
if user["balance"] < MIN_BAIL:
|
||||
return {"ok": False, "reason": "broke", "balance": user["balance"]}
|
||||
pct = random.uniform(0.20, 0.30)
|
||||
fine = max(MIN_BAIL, int(user["balance"] * pct))
|
||||
user["balance"] = max(0, user["balance"] - fine)
|
||||
user["jailed_until"] = None
|
||||
user["jailbreak_used"] = False
|
||||
user["lifetime_lost"] = user.get("lifetime_lost", 0) + fine
|
||||
user["total_bail_paid"] = user.get("total_bail_paid", 0) + fine
|
||||
await _commit(user_id, user)
|
||||
_txn("BAIL_PAID", user=user_id, fine=f"-{fine}", pct=f"{pct:.0%}", bal=user["balance"])
|
||||
return {"ok": True, "fine": fine, "balance": user["balance"]}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# /jailed
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
async def do_get_jailed() -> list[tuple[int, timedelta]]:
|
||||
"""Return [(user_id, remaining)] for every user currently in jail."""
|
||||
all_users = await get_all_users_raw()
|
||||
result: list[tuple[int, timedelta]] = []
|
||||
for uid_str, user in all_users.items():
|
||||
if rem := _is_jailed(user):
|
||||
result.append((int(uid_str), rem))
|
||||
result.sort(key=lambda x: x[1])
|
||||
return result
|
||||
Reference in New Issue
Block a user