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:
esefandClaude Opus 5.5 committed 2026-10-11 05:03:07 +03:00
commit 7e9cbee14d
33 files changed
+1890

No files matched your search

Executable
+42
View File
@@ -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()