Compare commits

..

No commits in common. "master" and "lundberg_add_black" have entirely different histories.

5 changed files with 3 additions and 95 deletions

2
.gitignore vendored
View file

@ -1,2 +0,0 @@
.venv
__pycache__

View file

@ -1,45 +0,0 @@
import httpx
from datetime import datetime, timedelta, timezone
from time import sleep
from main import TelemetrySnapshot
def main() -> None:
wait = 10
online_time = 24 * 3600 # start at 1 day
ew = 0
ns = 0
while True:
snapshot = TelemetrySnapshot(
character_name="Test name",
char_tag="test_tag",
session_id="test_session_id",
timestamp=datetime.now(tz=timezone.utc),
ew=ew,
ns=ns,
z=0,
kills=0,
kills_per_hour="kph_str",
onlinetime=str(timedelta(seconds=online_time)),
deaths=0,
rares_found=0,
prismatic_taper_count=0,
vt_state="test state",
)
resp = httpx.post(
"http://localhost:8000/position/",
data=snapshot.model_dump_json(),
headers={
"Content-Type": "application/json",
"X-PLUGIN-SECRET": "your_shared_secret",
},
)
print(resp)
sleep(wait)
ew += 0.1
ns += 0.1
online_time += wait
if __name__ == "__main__":
main()

40
main.py
View file

@ -3,7 +3,7 @@ import json
import sqlite3
from typing import Dict
from fastapi import FastAPI, Header, HTTPException, Query, WebSocket, WebSocketDisconnect
from fastapi import FastAPI, Header, HTTPException, Query
from fastapi.responses import JSONResponse
from fastapi.routing import APIRoute
from fastapi.staticfiles import StaticFiles
@ -11,8 +11,6 @@ from pydantic import BaseModel
from typing import Optional
from db import init_db, save_snapshot, DB_FILE
import asyncio
from starlette.concurrency import run_in_threadpool
# ------------------------------------------------------------------
app = FastAPI()
@ -196,42 +194,6 @@ def get_trails(
]
return JSONResponse(content={"trails": trails})
# -------------------- WebSocket endpoints -----------------------
browser_conns: set[WebSocket] = set()
async def _broadcast_to_browser_clients(snapshot: dict):
for ws in list(browser_conns):
try:
await ws.send_json(snapshot)
except WebSocketDisconnect:
browser_conns.remove(ws)
@app.websocket("/ws/position")
async def ws_receive_snapshots(websocket: WebSocket, secret: str = Query(...)):
await websocket.accept()
if secret != SHARED_SECRET:
await websocket.close(code=1008)
return
try:
while True:
data = await websocket.receive_json()
snap = TelemetrySnapshot.parse_obj(data)
live_snapshots[snap.character_name] = snap.dict()
await run_in_threadpool(save_snapshot, snap.dict())
await _broadcast_to_browser_clients(snap.dict())
except WebSocketDisconnect:
pass
@app.websocket("/ws/live")
async def ws_live_updates(websocket: WebSocket):
await websocket.accept()
browser_conns.add(websocket)
try:
while True:
await asyncio.sleep(3600)
except WebSocketDisconnect:
browser_conns.remove(websocket)
# -------------------- static frontend ---------------------------
app.mount("/", StaticFiles(directory="static", html=True), name="static")

View file

@ -209,8 +209,6 @@ function render(players) {
<span class="stat kph">${p.kills_per_hour}</span>
<span class="stat rares">${p.rares_found}</span>
<span class="stat meta">${p.vt_state}</span>
<span class="stat onlinetime">${p.onlinetime}</span>
<span class="stat deaths">${p.deaths}</span>
`;
li.addEventListener('click', () => selectPlayer(p, x, y));

View file

@ -156,12 +156,11 @@ body {
#playerList li {
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: auto auto auto auto;
grid-template-rows: auto auto auto;
grid-template-areas:
"name loc"
"kills kph"
"rares meta"
"onlinetime deaths";
"rares meta";
gap: 4px 8px;
margin: 6px 0;
padding: 8px 10px;
@ -179,8 +178,6 @@ body {
.stat.kph { grid-area: kph; }
.stat.rares { grid-area: rares; }
.stat.meta { grid-area: meta; }
.stat.onlinetime { grid-area: onlinetime; }
.stat.deaths { grid-area: deaths; }
/* pill styling */
#playerList li .stat {
@ -201,8 +198,6 @@ body {
background: var(--accent);
color: #111;
}
.stat.onlinetime::before { content: "🕑 "}
.stat.deaths::before { content: "💀 "}
/* hover & selected states */
#playerList li:hover { background: var(--card-hov); }