# Good to go. Thank you. import base64 import socket import sys import scrypt from collections import defaultdict from urllib.parse import parse_qs HOST = "" PORT = 10701 PASSWORD_HASH = b'I\xb5\xf1\xee8\xf0\r\xf0\xd2I\x16\x9f\xc8c\xef_]m\x81\xdf\xf0\xac\x8b\x05\x19\xe2\xef\xe6\xc6\x04\x16\xfd\x94\x0fP\xd5d\xbe&\x16}\x99E\x9e\x9f/I\xb4\xbaT\x1cJ\xfeRM\xe7\xbf\x9d\x1a\x07\xcd\xa0U%' def respond(conn, *, code=200, reason="OK", headers=None, body=""): headers = {"Content-Type": "text/html; charset=UTF-8", "Content-Length": len(body.encode()), "Connection": "close"} | (headers or {}) header_string = "" for key, value in headers.items(): header_string += f"{key}: {value}\r\n" r = f"HTTP/1.1 {code} {reason}\r\n{header_string}\r\n{body}".encode() conn.sendall(r) conn.close() def authenticate(conn, headers): if credentials := headers.get(b"Authorization"): try: username, password = base64.b64decode(credentials.removeprefix(b"Basic ")).split(b":") except: pass else: if username == b"host" and scrypt.hash(password, b"host", 1<<17) == PASSWORD_HASH: return True respond(conn, code=401, reason="Unauthorized", headers={"WWW-Authenticate": 'Basic realm="Access to admin panel"'}) return False def meson_loads(s): stack = [] for word in s.split(" "): if all(c.isascii() and c.isdigit() or c == "_" for c in word): stack.append(int(word.strip("_"))) elif word[0] == '"': stack.append(word[1:].replace("%20", " ").replace("%0A", "\n").replace("%09", "\t").replace("%0B", "\v").replace("%25", "%")) elif word[0] == "(" and word[-1] == ")" and all(x == "," for x in word[1:-1]): n = len(word)-1 stack[-n:], t = (), stack[-n:] stack.append(tuple(t)) elif word == "[]": c = stack.pop() if not isinstance(c, int): raise ValueError("[] popped non-integer") stack[-c:], t = (), stack[:-c-1:-1] stack.append(t) elif word == "{}": c = stack.pop() if not isinstance(c, int): raise ValueError("{} popped non-integer") stack[-c:], t = (), stack[:-c-1:-1] stack.append(set(t)) else: raise ValueError(f"unknown command '{word}'") return stack[-1] def meson_dumps(v): s = "" match v: case int(n): s += str(n) case str(x): s += '"' + x.replace(" ", "%20").replace("\n", "%0A").replace("\t", "%09").replace("\v", "%0B").replace("%", "%25") case tuple(t): if len(t) == 0: raise ValueError("cannot encode empty tuple") for x in t: s += meson_dumps(x) + " " s += "(" + ","*(len(t)-1) + ")" case list(l): for x in l[::-1]: s += meson_dumps(x) + " " s += str(len(l)) + " []" case set(xs): for x in xs: s += meson_dumps(x) + " " s += str(len(xs)) + " {}" case x: raise ValueError(f"unserializable value '{x!r}'") return s css = """ body { margin: auto; max-width: 400px; background: #f9f8f5; color: #49483e; font-family: sans-serif; font-size: 1.3em; line-height: 1.4em; } h1, p { text-align: center; line-height: 0.6em; } #rules { max-width: 700px; } li { margin-bottom: 10px; } """ html = { "404.html": """


Back to the main page

""", "index.html": """

Gambling Royale


""", "rules.html": """


Back to main page

  1. Every player begins with 5 points.
  2. 24 hours before the end of the guessing phase, the identity of the creator of the Gambling Royale will be revealed to the player (or players) with the most points.
  3. The author will additionally abstain from including the winner(s) in their guesses.
  4. Should the author fail to uphold these rules, they may be disqualified from the round.
  5. At any point in time, two or more people may participate in a game with points as the stakes.
  6. To begin a game, a thread should be created in the #event-discussion channel on Esolangs. The game's rules, and the stakes, are to be outlined and agreed upon by all parties who wish to play.
  7. Once the game has concluded, the user Host#1103 should be mentioned in the thread with the result. The point totals of the participants will be updated shortly.
  8. In the event of a dispute over the rules of the game, Host should be mentioned to resolve the dispute. Their word is final.
  9. Nothing other than points may be used as a wager in a game.
  10. Host will appear for 1 hour at 12-hour intervals, at 00:00 UTC and 12:00 UTC. You may talk to them at these times if you have any questions about the Royale.
""", "admin.html": """
""" } try: with open("save.meson") as f: points = meson_loads(f.read()) except FileNotFoundError: points = [] with open("save.meson", "w") as f: f.write(meson_dumps(points)) def handle_request(s): conn, addr = s.accept() data = conn.recv(4096) head, body = data.split(b"\r\n\r\n") lines = head.split(b"\r\n") meth, path, ver = lines[0].split(b" ") headers = {} for line in lines[1:]: header, value = line.split(b": ") headers[header] = value if ver != b"HTTP/1.1": respond(conn, code=505, reason="HTTP Version Not Supported") elif path == b"/admin": if authenticate(conn, headers): if meth == b"POST": data = parse_qs(body.decode(), keep_blank_values=True) point_dict = defaultdict(int, points) try: if data["from"][0]: points[data["from"][0]] -= int(data["amount"][0]) if data["to"][0]: points[data["to"][0]] += int(data["amount"][0]) except KeyError: respond(conn, code=400, reason="Bad Request", body="

400 Bad Request

") points[:] = point_dict.items() with open("save.meson", "w") as f: f.write(meson_dumps(points)) respond(conn, body=html["admin.html"]) elif meth != b"GET": respond(conn, code=405, reason="Method Not Allowed", headers={"Allow": "GET"}) elif path == b"/": lst = [] current = 1 last_score = None points.sort(key=lambda p: p[1], reverse=True) for idx, (name, score) in enumerate(points, start=1): if last_score is not None and score != last_score: current = idx last_score = score lst.append(f'
  • ({score}) {name}
  • ') respond(conn, body=html["index.html"].format(leaderboard="\n".join(lst))) elif path == b"/rules": respond(conn, body=html["rules.html"]) elif path == b"/main.css": respond(conn, body=css, headers={"Content-Type": "text/css"}) else: respond(conn, code=404, reason="Not Found", body=html["404.html"]) socket.setdefaulttimeout(1.0) with socket.create_server((HOST, PORT)) as s: port_str = f":{PORT}" if PORT != 80 else "" print(f"Listening on http://{HOST}{port_str}/", file=sys.stderr) while True: try: handle_request(s) except TimeoutError: pass