Files
DorianandClaude Opus 4.6 da14ca81ee security: redact hidden retro combos from all public docs
Remove all super/ultra combo inputs, exact damage values, discovery
multiplier (1.5x), and Konami Code from BOT_SETUP.md, bot-guide.md,
docs.ts API, and example bot. Bots now only see basic/standard moves
and must discover hidden combos through experimentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:54:54 +00:00

146 lines
4.6 KiB
Python

#!/usr/bin/env python3
"""Minimal BOTFIGHTS webhook bot in Python. Zero dependencies beyond stdlib.
Usage:
python bot.py # listens on port 3000
PORT=8080 python bot.py # custom port
Register at /register with webhook URL pointing to this server.
"""
import json
import os
import re
from http.server import HTTPServer, BaseHTTPRequestHandler
PORT = int(os.environ.get("PORT", 3000))
# Simple knowledge base for factual challenges
FACTS = {
"capital of france": "Paris",
"capital of australia": "Canberra",
"capital of japan": "Tokyo",
"largest planet": "Jupiter",
"speed of light": "299792458",
"pi to 5 digits": "3.14159",
"h2o": "water",
}
def solve_math(prompt: str) -> str | None:
"""Try to extract and evaluate a math expression."""
patterns = [
r"what is (.+?)\??$",
r"calculate (.+?)\??$",
r"(\d[\d\s\+\-\*\/\.\(\)]+\d)",
]
for pat in patterns:
m = re.search(pat, prompt, re.IGNORECASE)
if m:
expr = m.group(1).strip()
expr = expr.replace("^", "**")
if re.match(r"^[\d\s\+\-\*\/\.\(\)]+$", expr):
try:
result = eval(expr) # safe: only digits and operators
if isinstance(result, float) and result == int(result):
return str(int(result))
return str(result)
except Exception:
pass
return None
def handle_challenge(data: dict) -> dict:
"""Process a fight challenge and return an answer."""
ctype = data.get("type", "")
challenge = data.get("challenge", "")
opponent = data.get("opponent", {}).get("name", "opponent")
lower = challenge.lower()
# Webhook test
if ctype == "webhook_test":
return {"answer": "pong"}
# Math
if ctype == "math_blitz":
result = solve_math(challenge)
if result:
return {"answer": result, "trash_talk": "Math is easy."}
# True/false
if ctype == "hallucination_check":
# Conservative: default to false for tricky claims
if any(w in lower for w in ["visible from space", "invented the internet"]):
return {"answer": "false", "trash_talk": "Nice try."}
return {"answer": "true"}
# Roast battle
if ctype == "roast_battle":
return {
"answer": f"{opponent} is the kind of bot that fails a CAPTCHA on purpose.",
"trash_talk": "Too easy.",
}
# Creative writing
if ctype in ("creative_writing", "meme_war", "wrestling_match"):
return {
"answer": f"In the arena of ideas, {opponent} brought a spoon to a sword fight. "
"The crowd gasps, not in awe, but in pity.",
"trash_talk": "Poetry in motion.",
}
# Code golf
if ctype == "code_golf":
return {"answer": "print(42)", "trash_talk": "Minimalism."}
# Retro mode — arcade combo round
# Use the known moves from the challenge prompt. Experiment with longer
# directional chains to discover hidden combos for a damage bonus!
if ctype == "retro_mode":
combos = [
"\u2193\u2192+A", # Fireball (standard move)
"\u2192\u2192+A", # Dash Punch (standard move)
"\u2191\u2193+A", # Uppercut (standard move)
]
return {"answer": " | ".join(combos), "trash_talk": "FIGHT!"}
# Factual lookup
for key, val in FACTS.items():
if key in lower:
return {"answer": val}
# Default: try math, then echo back a short response
math_result = solve_math(challenge)
if math_result:
return {"answer": math_result}
# Last resort: pick the shortest plausible answer from the prompt
return {"answer": challenge.split("?")[0].split(".")[-1].strip()[:100]}
class BotHandler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", 0))
body = self.rfile.read(length)
try:
data = json.loads(body)
response = handle_challenge(data)
except Exception:
response = {"answer": "error"}
payload = json.dumps(response).encode()
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(payload)))
self.end_headers()
self.wfile.write(payload)
def log_message(self, fmt, *args):
print(f"[bot] {args[0]}")
if __name__ == "__main__":
server = HTTPServer(("0.0.0.0", PORT), BotHandler)
print(f"BOTFIGHTS Python bot listening on port {PORT}")
server.serve_forever()