cs16-dm-server: CS 1.6 deathmatch server in Docker
One-command setup (SteamCMD + pinned, checksum-verified ReHLDS / ReGameDLL / Metamod-R / AMXX / ReAPI / ReUnion / CSDM-ReAPI / YaPB / GunGame), .env settings, ./cs menu (map, DM/GunGame mode, bots, kill counter, restart, update), own plugins (extras, rtv, mode switch), all-time kill counter, watchdog + nightly backup, docs for admins and players. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
commit
7e9cbee14d
33 files changed
+1890
No files matched your search
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
"""All-time kill counter (bots and humans).
|
||||
./kills show the scoreboard (and save the tally)
|
||||
Counts the " killed " lines in hlds/cstrike/logs. Per-log counts are kept in kills-tally.json,
|
||||
so the totals survive scripts/backup.sh deleting logs older than 30 days (it runs this first)."""
|
||||
import collections, json, os, re
|
||||
|
||||
D = os.path.dirname(os.path.abspath(__file__))
|
||||
LOGS = os.path.join(D, "hlds", "cstrike", "logs")
|
||||
STATE = os.path.join(D, "kills-tally.json")
|
||||
KILL = re.compile(r'^L (\d\d/\d\d/\d{4}) - [\d:]+: "(.+?)<\d+><[^>]*><[^>]*>" killed '
|
||||
r'".+?<\d+><[^>]*><[^>]*>" with "([^"]+)"')
|
||||
|
||||
try:
|
||||
st = json.load(open(STATE))
|
||||
except (OSError, ValueError):
|
||||
st = {"files": {}}
|
||||
for f in sorted(os.listdir(LOGS)) if os.path.isdir(LOGS) else []:
|
||||
if not f.endswith(".log"):
|
||||
continue
|
||||
n, who, wpn, days = 0, collections.Counter(), collections.Counter(), set()
|
||||
for line in open(os.path.join(LOGS, f), encoding="utf-8", errors="replace"):
|
||||
m = KILL.match(line)
|
||||
if m:
|
||||
n += 1; days.add(m[1]); who[m[2]] += 1; wpn[m[3]] += 1
|
||||
if n or f not in st["files"]:
|
||||
st["files"][f] = {"kills": n, "who": who, "wpn": wpn, "days": sorted(days)}
|
||||
tmp = STATE + ".tmp"
|
||||
json.dump(st, open(tmp, "w"))
|
||||
os.replace(tmp, STATE)
|
||||
|
||||
total, who, wpn, days = 0, collections.Counter(), collections.Counter(), set()
|
||||
for v in st["files"].values():
|
||||
total += v["kills"]; who.update(v["who"]); wpn.update(v["wpn"]); days.update(v["days"])
|
||||
print(f"\n ALL-TIME KILLS: {total:,} ({len(days)} days of carnage, {len(st['files'])} maps played)\n")
|
||||
print(" top fraggers:")
|
||||
for i, (n, k) in enumerate(who.most_common(5), 1):
|
||||
print(f" {i}. {n:<18} {k:,}")
|
||||
print("\n weapons of choice:")
|
||||
for n, k in wpn.most_common(5):
|
||||
print(f" {n:<18} {k:,}")
|
||||
print()
|
||||
Reference in new issue
Block a user