Add social_id ban list - #240
Draft
KarmicP wants to merge 7 commits into
Draft
Conversation
KarmicP
force-pushed
the
feat/social-id-bans
branch
from
August 22, 2026 08:57
9ac801b to
97d91d8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A ban list that survives restarts, stored against the player's
social_id— the account id the engine gives us (a Steam ID on Steam builds). It doesn't change when someone renames or reconnects from a new address, so those two ways round a ban don't work.Draft, because there are two questions at the bottom I'd rather ask than guess at. Happy to change anything.
What it does
Three admin commands next to
boot, same permissions:ban <client num> [reason]— bans and removes the playerunban <social_id>— lifts a banbanlist— lists current bansBans live in
baseq2/bans.cfg, one per line associal_id|name|reason. Read at startup, rewritten on change (via a temp file, so an interrupted write can't corrupt it). Only the id matters; the name is there for readability. Comments you add by hand won't survive a rewrite.Bots and unauthenticated players have no
social_id, so they can't be banned —bansays so and kicks instead.Most of the code is three new files under
src/sgame/muffmode/; the record handling is engine-free and covered by 7 new offline tests (suite goes 60 → 67, all passing). The rest is small: load at startup, a check at the top ofClientConnect, and the commands.A
bootfix, in its own commitThe engine's
kickwants a lobby user number, butbootpassed the entity index — always exactly one higher, sinceP_GetLobbyUserNumis(player - g_entities) - 1. Soboot 3acted on the next slot along, and on an empty slot the engine could call into client code with no client attached. Your ownbot_utils.cpp:182already setslobby_usernumfromP_GetLobbyUserNum.I hit this because
banalso kicks and I didn't want to copy the bug into new code. It's a separate commit with its own changelog entry — revert that one commit and the ban list is unaffected. Happy to split it into its own PR instead.What it can't do
Refusing the connection doesn't get a banned player out of lobby chat, because the chat connection is set up before
ClientConnectruns. They can keep talking until their join attempt times out — 15–20 seconds when I tested.So the check also kicks them from the lobby, which cuts that to a frame or two. It doesn't close it completely: the chat connection exists before any game code runs and there's no hook for it, so a determined player still gets a moment per attempt. That needs an engine-side fix, which I can't reach.
Two questions
1.
banpicks its target differently fromboot. It takes a client number and reads it directly, rather than going throughClientEntFromString. That helper checks for an exact name match first, so a player named3gets picked up byban 3instead of whoever is in slot 3. Forbootthat's a passing annoyance; forbanit writes the wrong person's id to disk. I've leftbootalone — unlike the kick bug, that's a judgement call and yours to make. Happy to align them either way.2. Where should this live on
main? You already store profiles bysocial_idthere, so folding bans in is an obvious alternative to a separate file. Butmm_client_profile.cppstrips a leftoverbannedfield alongsideadmin, under a comment about authority coming only from the authenticated admin system — which reads like a deliberate choice to keep ban status out of that file. You know why that code is there and I don't, so I'd rather ask. I'll match whichever you prefer when I port this.Base
0.60-stableatv0.60.20(3621fee). All new code apart from the onebootline: 480 added, 1 removed. Builds with MSVC, offline tests pass.