Add 6 tutorials (6 files)
Browse Source
6 changed files
with 282 additions and 0 deletions
A
amxmodmenu-guide/en.md
+49 -0
A
cs16-black-bars-aspect-ratio/en.md
+9 -0
A
cs16-footstep-sound-settings/en.md
+60 -0
A
fastdl-cloudflare-cdn/en.md
+57 -0
A
prevent-steamid-spoofing/en.md
+50 -0
A
reserved-slots-setup/en.md
+57 -0
amxmodmenu-guide/en.md
A
| @@ -0,0 +1,49 @@ | ||
| 1 | +--- | |
| 2 | +title: "Using amxmodmenu: A Tour of the Admin Menu" | |
| 3 | +excerpt: "What the amxmodmenu command opens, the menu plugins behind each submenu, how to bind a key to it, and why a submenu goes missing when its plugin is not loaded." | |
| 4 | +category: "administration" | |
| 5 | +tags: "menu, admin" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>Not every admin wants to memorise console commands. AMX Mod X ships an in-game menu system, opened with the <code>amxmodmenu</code> command, that puts kicking, banning, slapping, map changes and config toggles behind a keyboard-driven menu. It is the friendliest way to run a server, and understanding which plugin backs each submenu explains why an option sometimes simply is not there.</p> | |
| 10 | + | |
| 11 | +<h2>1. Open the menu</h2> | |
| 12 | +<p>From the console, or bound to a key, run:</p> | |
| 13 | +<pre>amxmodmenu</pre> | |
| 14 | +<p>This command comes from the <code>menufront.amxx</code> plugin — the front page that lists the submenus. If <code>amxmodmenu</code> is an unknown command, that plugin is not loaded; check your <a href="/tutorials/plugins-ini-load-order">plugins.ini</a>. The menu only opens for players AMXX recognises as admins, and each option inside is further gated by your <a href="/tutorials/amxx-admin-flags-reference">access flags</a>.</p> | |
| 15 | + | |
| 16 | +<h2>2. Bind it to a key</h2> | |
| 17 | +<p>Typing the command every time is tedious. Bind it to a spare key in your own config:</p> | |
| 18 | +<pre>bind "o" "amxmodmenu"</pre> | |
| 19 | +<p>Now pressing <code>o</code> opens the admin menu in-game. Navigate with the number keys the menu shows; the same number keys select targets and options as you drill in.</p> | |
| 20 | + | |
| 21 | +<h2>3. What each submenu does</h2> | |
| 22 | +<p>The front menu is a launcher for several separate menu plugins. The common entries and the plugins behind them:</p> | |
| 23 | +<ul> | |
| 24 | +<li><strong>Kick / Ban / Slap / Slay / Team menus</strong> — backed by <code>plmenu.amxx</code> (the players menu). Pick a player from a list, then the action, without typing a userid.</li> | |
| 25 | +<li><strong>Commands menu</strong> — backed by <code>cmdmenu.amxx</code>. Toggles common cvars and server settings, restarts the round, and similar one-click actions.</li> | |
| 26 | +<li><strong>Map menu</strong> — backed by <code>mapsmenu.amxx</code>. Change level or start a map vote from a list of installed maps.</li> | |
| 27 | +<li><strong>Speech / Client-commands menus</strong> — backed by the menu plugins that expose those actions (for example <code>telemenu.amxx</code> where teleport/speech features are enabled).</li> | |
| 28 | +</ul> | |
| 29 | +<p>Each of these is a distinct plugin listed in <code>plugins.ini</code>. The front menu only shows an entry if its backing plugin is loaded — which is the key to the next section.</p> | |
| 30 | + | |
| 31 | +<h2>4. A missing submenu means a missing plugin</h2> | |
| 32 | +<p>If the Map menu, or the Kick menu, or any entry is absent from your <code>amxmodmenu</code>, the cause is almost always that the plugin behind it is commented out or failed to load. Check what actually loaded:</p> | |
| 33 | +<pre>amxx plugins</pre> | |
| 34 | +<p>Look for <code>plmenu.amxx</code>, <code>cmdmenu.amxx</code>, <code>mapsmenu.amxx</code> and <code>menufront.amxx</code> reading <code>running</code>. A <code>bad load</code> or a commented line in <code>plugins.ini</code> removes the corresponding menu entry. Re-enable the plugin, change the map, and the option returns. A submenu can also be empty if <em>your</em> admin account lacks the access flags those actions require — the plugin is loaded but the menu has nothing you are allowed to do.</p> | |
| 35 | + | |
| 36 | +<h2>5. Menu versus commands</h2> | |
| 37 | +<p>The menu is a convenience layer over the same commands covered in the <a href="/tutorials/amx-slap-slay-kick">slap/slay/kick guide</a> and the <a href="/tutorials/amx-ban-commands">ban commands</a> — choosing "Kick" and a player runs <code>amx_kick</code> under the hood. Use the menu for speed in the heat of a match; drop to the console when you need something the menu does not expose, such as a precise ban duration or targeting by exact userid. For a richer, configurable admin menu with more actions than the stock one, see the <a href="/plugins/csb-admin-menu">CSB Admin Menu</a>.</p> | |
| 38 | + | |
| 39 | +<h2>Common errors</h2> | |
| 40 | +<ul> | |
| 41 | +<li><strong><code>Unknown command: amxmodmenu</code></strong> — <code>menufront.amxx</code> is not loaded. Add it to <code>plugins.ini</code> and change the map.</li> | |
| 42 | +<li><strong>Menu opens but is nearly empty</strong> — your admin account lacks the access flags the submenus need, or the backing menu plugins are not loaded. Check <code>amx_who</code> and <code>amxx plugins</code>.</li> | |
| 43 | +<li><strong>A whole submenu is missing</strong> — the plugin behind it (<code>plmenu</code>, <code>cmdmenu</code>, <code>mapsmenu</code>) is commented out or <code>bad load</code>. Re-enable it.</li> | |
| 44 | +<li><strong>Menu does not respond to number keys</strong> — another plugin is intercepting the same menu keys. This is a load-order conflict; see <a href="/tutorials/plugins-ini-load-order">load order</a>.</li> | |
| 45 | +<li><strong>Non-admins can open it</strong> — a flag was left in <code>amx_default_access</code>, granting menu access to everyone. Clear that cvar in <a href="/tutorials/amxx-cfg-explained">amxx.cfg</a>.</li> | |
| 46 | +</ul> | |
| 47 | + | |
| 48 | +<h2>Verification</h2> | |
| 49 | +<p>Bind the key, join as an admin, and open the menu. Confirm each expected submenu is present and that selecting Kick lists connected players. Perform a harmless action — slap yourself through the menu — and confirm it behaves exactly as the console command would, including the activity message players see. If an entry you want is missing, run <code>amxx plugins</code> and re-enable its backing plugin rather than looking for a setting inside the menu itself.</p> |
cs16-black-bars-aspect-ratio/en.md
A
| @@ -0,0 +1,9 @@ | ||
| 1 | +--- | |
| 2 | +title: "Fix: Black Bars / Wrong Aspect Ratio in CS 1.6" | |
| 3 | +excerpt: "Why CS 1.6 shows black bars on a widescreen monitor, the difference between stretched and centered scaling, how to set a native 16:9 resolution, and the GPU control-panel setting that removes the bars." | |
| 4 | +category: "client" | |
| 5 | +tags: "resolution, display" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>You launch CS 1.6 on a modern widescreen monitor and get a 4:3 image floating in the middle with thick black bars on either side, or a stretched, distorted picture. This is a display-scaling problem, not a bug in the game: CS defaults to a 4:3 resolution, and how your GPU maps that onto a 16:9 panel decides whether you get bars, stretch, or a correct widescreen image. Here is how to control it.</p><h2>1. Understand what is happening</h2><p>CS 1.6 renders at whatever resolution you pick. On an old 4:3 monitor, <code>640x480</code> or <code>1024x768</code> filled the screen. On a 16:9 panel, a 4:3 resolution has three possible outcomes depending on your GPU's scaling mode:</p><ul><li><strong>Aspect / centered</strong> — the 4:3 image is shown at its true ratio with black bars filling the unused width. Correct proportions, wasted screen.</li><li><strong>Stretched / full-screen</strong> — the 4:3 image is stretched to fill 16:9, so everything looks wide and models look fat. No bars, wrong shapes.</li><li><strong>Native widescreen</strong> — you pick an actual 16:9 resolution and the image fills the panel correctly. This is what you want.</li></ul><h2>2. Pick a native widescreen resolution in-game</h2><p>The cleanest fix is to run a resolution that matches your monitor's aspect ratio. In the game: <strong>Options → Video</strong>, set the resolution to a 16:9 value your panel supports (for a 1080p monitor, <code>1280x720</code> or <code>1920x1080</code>), and make sure the renderer is OpenGL. You can also set it from launch options in Steam (right-click CS → Properties → Set Launch Options):</p><pre>-w 1280 -h 720</pre><p>With a true 16:9 resolution there is no aspect mismatch, so there are no bars and no stretch — the GPU has nothing to letterbox. Many competitive players still prefer 4:3 for the larger-feeling models, and accept either bars or stretch as a trade-off; if you are one of them, use the GPU setting below to choose which.</p><h2>3. If you want 4:3, set GPU scaling deliberately</h2><p>To play a 4:3 resolution and choose bars vs stretch, set the scaling mode in your GPU control panel — not in the game:</p><ul><li><strong>NVIDIA</strong> — NVIDIA Control Panel → Display → Adjust desktop size and position. Choose <em>Full-screen</em> to stretch (no bars) or <em>Aspect ratio</em> to keep bars, and set "Perform scaling on" to <em>GPU</em>. Enabling "Override the scaling mode set by games" makes it stick.</li><li><strong>AMD</strong> — AMD Software → Display → Scaling Mode. <em>Full panel</em> stretches, <em>Preserve aspect ratio</em> keeps bars, <em>Center</em> shows the image 1:1 in the middle.</li><li><strong>Intel</strong> — Intel Graphics Command Center → Display → Scale. <em>Full Screen</em> stretches, <em>Maintain Aspect Ratio</em> keeps bars, <em>Center Image</em> shows it 1:1.</li></ul><p>The key detail people miss: on many setups the <strong>monitor</strong> also has its own scaling, and it can override the GPU. If the GPU setting does nothing, the display is doing the scaling — set the GPU to "perform scaling on GPU" so the graphics card wins, or change the monitor's aspect setting in its on-screen menu.</p><h2>4. Full-screen vs windowed</h2><p>Scaling only applies in exclusive full-screen. If you launch with <code>-window</code> or <code>-noborder</code>, the game is a window on your desktop and the GPU scaling modes do not apply — the window is simply its pixel size. If you use borderless windowed at your desktop resolution with a 4:3 <em>aspect</em>, you will see bars that no GPU setting removes because it is a window, not a scaled full-screen surface. For the scaling options above to work, run full-screen.</p><h2>Common errors</h2><ul><li><strong>Image is stretched and models look fat</strong> — a 4:3 resolution with GPU/monitor scaling set to full-screen/stretch. Switch to a 16:9 resolution or set scaling to "Aspect ratio".</li><li><strong>Bars remain no matter the GPU setting</strong> — the monitor is doing the scaling. Set "Perform scaling on GPU" (NVIDIA) or change the monitor's own aspect setting.</li><li><strong>GPU scaling greyed out</strong> — you are on a laptop's internal panel, or the desktop is already at native res with nothing to scale. Change the in-game resolution first.</li><li><strong>Setting reverts after launch</strong> — "Override the scaling mode set by games" is off (NVIDIA); enable it.</li><li><strong>No bars but blurry</strong> — you are upscaling a low 4:3 resolution to a high-res panel. Raise the in-game resolution.</li></ul><h2>Verification</h2><p>Load a map and look at a round object — a barrel, a player model's head. If circles are round and the image fills the screen, the aspect ratio is correct. If it fills the screen but circles are ovals, you are stretched; if circles are round but there are bars, you are in aspect mode. Adjust the in-game resolution and the GPU scaling mode until you get the combination you want. If the game will not reach the desktop at all — a truly black screen on launch rather than bars — that is a different problem; see <a href="/tutorials/cs16-black-screen-launch">the black screen on launch fix</a>.</p> |
cs16-footstep-sound-settings/en.md
A
| @@ -0,0 +1,60 @@ | ||
| 1 | +--- | |
| 2 | +title: "CS 1.6 Sound Settings for Clearer Footsteps" | |
| 3 | +excerpt: "Tune CS 1.6 audio so footsteps and reloads cut through: sound quality, disabling music, high-quality sound, and why some clarity settings are server-controlled." | |
| 4 | +category: "client" | |
| 5 | +tags: "sound, settings" | |
| 6 | +image: "" | |
| 7 | +read_time: "7 min read" | |
| 8 | +--- | |
| 9 | +<p>In CS 1.6, hearing an enemy before you see them wins rounds. Footsteps, reloads and weapon switches are quiet, positional cues that are easy to lose under loud music, low sound quality, or muddy processing. This tunes the client audio so those cues are as clear and locatable as the engine allows — and is honest about the parts you cannot control from your side.</p> | |
| 10 | + | |
| 11 | +<h2>1. Set sound quality to high</h2> | |
| 12 | +<p>The single biggest client-side gain is running the game's high-quality sound path. In <strong>Options → Audio</strong>, set the sound quality to <strong>High</strong>. The console equivalent is:</p> | |
| 13 | +<pre>hisound 1</pre> | |
| 14 | +<p><code>hisound 1</code> uses the higher sample rate, which makes footsteps sharper and easier to place. On modern hardware there is no reason to run the low-quality path.</p> | |
| 15 | + | |
| 16 | +<h2>2. Kill the music and menu sounds</h2> | |
| 17 | +<p>Round-start and bomb-planted music masks footsteps at exactly the wrong moments. Turn the music channels down to zero:</p> | |
| 18 | +<pre>MP3Volume 0 | |
| 19 | +bgmvolume 0</pre> | |
| 20 | +<p><code>MP3Volume</code> controls the in-game music tracks and <code>bgmvolume</code> the CD/background music channel. Silencing both means the only thing in your ears is the game world.</p> | |
| 21 | + | |
| 22 | +<h2>3. Balance the master and voice levels</h2> | |
| 23 | +<p>Set your master volume high enough that quiet footsteps are audible, but leave headroom so a gunshot does not blow your ears out:</p> | |
| 24 | +<pre>volume 0.8 | |
| 25 | +suitvolume 0.25 | |
| 26 | +voice_scale 0.8</pre> | |
| 27 | +<p>If teammate voice chat is drowning game audio, lower <code>voice_scale</code> rather than dropping the master. The goal is a mix where a distant step is still present under the louder sounds.</p> | |
| 28 | + | |
| 29 | +<h2>4. Avoid muddy processing</h2> | |
| 30 | +<p>Older builds exposed environmental audio effects (EAX / A3D reverb) that smear positional cues. Where those cvars exist, keep them off for a dry, precise sound:</p> | |
| 31 | +<pre>s_eax 0 | |
| 32 | +s_a3d 0</pre> | |
| 33 | +<p>On the current Steam build these may not do anything, but on setups that still expose them, reverb makes footsteps sound "everywhere" and harder to pin down. A dry signal locates better.</p> | |
| 34 | + | |
| 35 | +<h2>5. Use stereo headphones, not surround virtualisation</h2> | |
| 36 | +<p>CS 1.6's audio is stereo, and the engine's own left-right panning is what tells you which side a step came from. Layering a Windows or driver "virtual 7.1" surround effect on top of that often smears the panning the game is already doing, so a distant footstep that should be cleanly to your left ends up vague. For competitive play, set your headphones to plain <strong>stereo</strong> in the Windows sound settings and let the game position the audio. Real headphones also beat speakers here — speakers bleed left and right together and you lose the directional cue entirely. None of this is a cvar, but it is the difference between hearing "someone is nearby" and hearing "someone is on my right, close."</p> | |
| 37 | + | |
| 38 | +<h2>6. Keep the audio engine responsive</h2> | |
| 39 | +<p>A small mix-ahead buffer keeps sound tight to the action; too large and audio lags the visuals. The default is usually fine, but if your sound feels delayed:</p> | |
| 40 | +<pre>_snd_mixahead 0.1 | |
| 41 | +snd_noextraupdate 0</pre> | |
| 42 | +<p>Save all of these in your <a href="/tutorials/cs16-competitive-video-config">autoexec.cfg</a> so they persist, since the audio menu can rewrite some of them on exit.</p> | |
| 43 | + | |
| 44 | +<h2>7. Know what you cannot change</h2> | |
| 45 | +<p>Some of footstep audibility is not yours to set. Whether footsteps exist at all is a <strong>server</strong> cvar, <code>mp_footsteps</code>: with <code>mp_footsteps 0</code> the server makes movement silent for everyone and no client setting brings the steps back. That, and the movement-speed rules, are covered in the <a href="/tutorials/mp-cvars-reference">mp_ cvars reference</a>. If a specific server has silent movement, that is a deliberate server choice, not a bug in your audio.</p> | |
| 46 | + | |
| 47 | +<h2>Common errors</h2> | |
| 48 | +<ul> | |
| 49 | +<li><strong>Music still plays over footsteps</strong> — only one music channel was muted. Set both <code>MP3Volume 0</code> and <code>bgmvolume 0</code>.</li> | |
| 50 | +<li><strong>Footsteps sound smeared or echoey</strong> — environmental effects are on. Set <code>s_eax 0</code> and <code>s_a3d 0</code> where available.</li> | |
| 51 | +<li><strong>No footsteps at all on one server</strong> — that server runs <code>mp_footsteps 0</code>. Nothing to fix client-side.</li> | |
| 52 | +<li><strong>Audio lags the action</strong> — mix-ahead too large; lower <code>_snd_mixahead</code> toward 0.1.</li> | |
| 53 | +<li><strong>Settings reset each launch</strong> — you set them only in the menu or in <code>config.cfg</code>. Put them in <code>autoexec.cfg</code>.</li> | |
| 54 | +</ul> | |
| 55 | + | |
| 56 | +<h2>Verification</h2> | |
| 57 | +<p>Load a map with a bot or a friend, stand still, and have them walk and reload nearby. You should hear each footstep clearly and be able to tell left from right and near from far. Read a value back to confirm it stuck:</p> | |
| 58 | +<pre>hisound | |
| 59 | +MP3Volume</pre> | |
| 60 | +<p>The console echoes each. If footsteps are crisp offline but absent on a particular server, check whether that server disabled them with <code>mp_footsteps</code> — an audio problem you can hear everywhere is yours to fix, one confined to a single server usually is not.</p> |
fastdl-cloudflare-cdn/en.md
A
| @@ -0,0 +1,57 @@ | ||
| 1 | +--- | |
| 2 | +title: "Hosting FastDL Behind Cloudflare (Free CDN)" | |
| 3 | +excerpt: "Put your CS 1.6 FastDL mirror behind Cloudflare's free CDN: point sv_downloadurl at a proxied domain, force caching of .bsp and .bz2 with a Cache Rule, and avoid the file-type caching trap." | |
| 4 | +category: "administration" | |
| 5 | +tags: "fastdl, cloudflare" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>If your FastDL host is a single VPS, every joining player pulls maps straight from it — fine until a popular map change sends fifty clients at your origin at once. Putting the mirror behind Cloudflare's free CDN caches those static files at the edge, so the second and every subsequent client downloads from a nearby Cloudflare node instead of hammering your box. It is free and effective, but Cloudflare does not cache <code>.bsp</code> and <code>.bz2</code> by default, and that trap is why most \"Cloudflare FastDL\" attempts see no benefit.</p> | |
| 10 | + | |
| 11 | +<h2>1. Prerequisite: a working origin mirror</h2> | |
| 12 | +<p>Cloudflare sits in front of a real web server — it does not host files itself. Get a normal <a href="/tutorials/fastdl-setup-guide">FastDL mirror</a> working first, with the correct <code>cstrike/</code> path layout and, ideally, <a href="/tutorials/fastdl-bzip2-compression">bzip2-compressed files</a>. Confirm the origin serves a map over plain HTTP before adding the CDN. Cloudflare cannot fix a broken origin path; it will just cache the 404.</p> | |
| 13 | + | |
| 14 | +<h2>2. Put the domain on Cloudflare and proxy it</h2> | |
| 15 | +<p>Add your domain to Cloudflare, then create a DNS record for the FastDL subdomain pointing at your origin IP, with the proxy (orange cloud) <strong>on</strong>:</p> | |
| 16 | +<pre>Type Name Content Proxy | |
| 17 | +A dl 203.0.113.10 Proxied (orange cloud)</pre> | |
| 18 | +<p>Proxied is what routes traffic through Cloudflare's edge and enables caching. A \"DNS only\" (grey cloud) record points clients straight at your origin and gives you no CDN at all. Then set <code>sv_downloadurl</code> to the proxied hostname:</p> | |
| 19 | +<pre>// server.cfg | |
| 20 | +sv_downloadurl "http://dl.example.com/cs"</pre> | |
| 21 | +<p>HTTPS works too and Cloudflare gives you a certificate; just make sure the origin also answers so Cloudflare can fetch and cache.</p> | |
| 22 | + | |
| 23 | +<h2>3. Force caching of game files (the essential step)</h2> | |
| 24 | +<p>Cloudflare's default cache only covers a fixed list of static extensions — images, CSS, JS — and <code>.bsp</code>, <code>.bz2</code>, <code>.mdl</code>, <code>.wav</code>, <code>.spr</code> are <strong>not</strong> on it. Left alone, Cloudflare passes every game-file request through to your origin and caches nothing, defeating the whole exercise. Fix it with a Cache Rule (the modern replacement for Page Rules) that forces these files into the cache. In the dashboard under <em>Caching → Cache Rules</em>, create a rule:</p> | |
| 25 | +<pre>When incoming requests match: | |
| 26 | + (http.request.uri.path.extension in {"bsp" "bz2" "mdl" "wav" "spr"}) | |
| 27 | +Then: | |
| 28 | + Cache eligibility: Eligible for cache | |
| 29 | + Edge TTL: override, e.g. 7 days</pre> | |
| 30 | +<p>Alternatively, match the whole path prefix — <code>http.request.uri.path contains "/cstrike/"</code> — and mark it eligible. Either way you are telling Cloudflare \"these are static, cache them,\" which it will not assume on its own.</p> | |
| 31 | + | |
| 32 | +<h2>4. Why this is worth it</h2> | |
| 33 | +<ul> | |
| 34 | +<li><strong>Origin offload</strong> — after the first request per file per edge, downloads are served from Cloudflare, so a crowd joining after a map change hits the CDN, not your VPS.</li> | |
| 35 | +<li><strong>Geographic speed</strong> — players download from a nearby edge node rather than your single location, which matters for an international audience.</li> | |
| 36 | +<li><strong>Bandwidth</strong> — Cloudflare's free plan does not bill egress for cached static content, so your origin bandwidth bill drops sharply.</li> | |
| 37 | +<li><strong>Basic protection</strong> — the origin IP is hidden behind Cloudflare, reducing direct abuse of the download host.</li> | |
| 38 | +</ul> | |
| 39 | + | |
| 40 | +<h2>5. Confirm files are actually being cached</h2> | |
| 41 | +<p>The proof is the <code>cf-cache-status</code> response header. Request a map file twice and watch it go from <code>MISS</code> (fetched from origin) to <code>HIT</code> (served from edge):</p> | |
| 42 | +<pre>curl -sI https://dl.example.com/cs/cstrike/maps/de_rats.bsp.bz2 | grep -i cf-cache | |
| 43 | +# first: cf-cache-status: MISS | |
| 44 | +# second: cf-cache-status: HIT</pre> | |
| 45 | +<p>If it stays <code>MISS</code> or shows <code>DYNAMIC</code>, your Cache Rule is not matching — recheck the extension list and that the rule is enabled.</p> | |
| 46 | + | |
| 47 | +<h2>Common errors</h2> | |
| 48 | +<ul> | |
| 49 | +<li><strong>No speed improvement, origin still hammered</strong> — <code>cf-cache-status</code> is <code>DYNAMIC</code>/<code>MISS</code>: the game extensions are not covered by a Cache Rule. Add the rule; Cloudflare does not cache <code>.bsp</code>/<code>.bz2</code> by default.</li> | |
| 50 | +<li><strong>Record is grey-cloud (DNS only)</strong> — traffic bypasses Cloudflare entirely. Set the FastDL record to Proxied.</li> | |
| 51 | +<li><strong>Downloads 404 through Cloudflare but work on the origin</strong> — the origin path is wrong (missing the <code>cstrike/</code> level). Cloudflare faithfully proxies the 404; fix the mirror layout.</li> | |
| 52 | +<li><strong>Stale file after you update a map</strong> — the edge cached the old copy. Purge that URL (or purge everything) in the Cloudflare cache panel after replacing content.</li> | |
| 53 | +<li><strong>Client falls back to slow in-game download over HTTPS</strong> — a TLS/cert error on the origin or an <code>Error 5xx</code> from Cloudflare. Confirm the origin answers and the certificate is valid.</li> | |
| 54 | +</ul> | |
| 55 | + | |
| 56 | +<h2>Verification</h2> | |
| 57 | +<p>End to end: request a map file through the Cloudflare hostname twice and confirm the second is a cache <code>HIT</code> (above). Then join the server from a client that lacks the map and watch it download quickly; check your origin's access log and confirm most requests after the first are absent because the edge is serving them. Keep the origin mirror and its <a href="/tutorials/fastdl-bzip2-compression">bzip2 files</a> in sync with your <a href="/tutorials/mapcycle-txt-setup">rotation</a>, and remember to purge the Cloudflare cache whenever you replace a file under an existing name.</p> |
prevent-steamid-spoofing/en.md
A
| @@ -0,0 +1,50 @@ | ||
| 1 | +--- | |
| 2 | +title: "Preventing SteamID Spoofing on Non-Steam Servers (Reunion + SteamIdHashSalt)" | |
| 3 | +excerpt: "Why non-steam clients can claim an admin's SteamID, how Reunion's SteamIdHashSalt closes the hole, and how to authenticate admins so they cannot be impersonated." | |
| 4 | +category: "security" | |
| 5 | +tags: "steamid, reunion" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>On a Steam server this problem does not exist: Steam validates every ticket, so a <code>STEAM_0:x:xxxx</code> ID is genuine and unique. On a <a href="/tutorials/steam-vs-nonsteam-servers">non-steam server</a> it is a real threat — without the right configuration a client can simply <em>claim</em> your head admin's SteamID and inherit full RCON-level access from <code>users.ini</code>. The fix is a secret salt in Reunion plus an admin auth method that cannot be forged. Here is how to close it properly.</p> | |
| 10 | + | |
| 11 | +<h2>1. Understand the attack</h2> | |
| 12 | +<p>Admins are usually granted access by SteamID in <a href="/tutorials/users-ini-explained">users.ini</a>:</p> | |
| 13 | +<pre>"STEAM_0:1:123456" "" "abcdefghijklmnopqrstu" "ce"</pre> | |
| 14 | +<p>On a non-steam server, the SteamID a client presents is only as trustworthy as your auth layer. If IDs are generated in a predictable or client-controlled way, an attacker who learns your admin's ID (it is often visible in <code>status</code> output or logs) can configure their client to present the same one and walk in with your flags. That is SteamID spoofing.</p> | |
| 15 | + | |
| 16 | +<h2>2. Set a strong SteamIdHashSalt in Reunion</h2> | |
| 17 | +<p><a href="/tutorials/install-reunion">Reunion</a> generates SteamIDs for non-steam clients by hashing client identity together with a server-side secret, the <code>SteamIdHashSalt</code>, set in <code>reunion.cfg</code> in your <code>cstrike</code> folder:</p> | |
| 18 | +<pre>SteamIdHashSalt = a_long_random_secret_string_16plus</pre> | |
| 19 | +<p>Two hard rules:</p> | |
| 20 | +<ul> | |
| 21 | +<li><strong>It must be at least 16 characters</strong> — Reunion refuses to load a salt shorter than that, and a short salt is guessable anyway. Use a long random string.</li> | |
| 22 | +<li><strong>Keep it secret and stable.</strong> The salt is what makes generated IDs unpredictable to an attacker. If it leaks, they can reproduce IDs; if you change it, <em>every</em> generated ID changes and all your SteamID-based admins lose access at once.</li> | |
| 23 | +</ul> | |
| 24 | +<p>With a strong, secret salt, a client can no longer reverse-engineer or trivially reproduce another player's generated ID.</p> | |
| 25 | + | |
| 26 | +<h2>3. Understand Reunion's auth providers</h2> | |
| 27 | +<p>Reunion recognizes clients from several providers (real Steam, its own generated non-steam IDs, and legacy revemu-style clients). The generated-ID path is the one the salt protects. Configure Reunion to accept the providers you actually want and to hand each client a salted, generated ID rather than trusting a client-supplied one. Read the provider settings in your <code>reunion.cfg</code> — do not accept a mode that lets the client dictate its own SteamID unchecked.</p> | |
| 28 | + | |
| 29 | +<h2>4. Authenticate admins by something unspoofable</h2> | |
| 30 | +<p>Even with a good salt, the most robust protection for high-privilege admins is to not rely on SteamID alone. AMX Mod X supports password authentication: the admin sets a client-side <code>setinfo</code> value and <code>users.ini</code> requires it. Use the flags that demand a password rather than pure SteamID matching:</p> | |
| 31 | +<pre>// users.ini entry that requires a password (flag "a" = do not check steamid, | |
| 32 | +// authenticate by the name+password fields instead) | |
| 33 | +"MyAdminName" "SecretPass" "abcdefghijklmnopqrstu" "a"</pre> | |
| 34 | +<pre>// the admin sets this in their client config | |
| 35 | +setinfo _pw "SecretPass"</pre> | |
| 36 | +<p>Now an attacker who knows the SteamID still cannot get in without the password. Reserve this for the accounts that matter most; the exact flag semantics are in the <a href="/tutorials/amxx-admin-flags-reference">access flags reference</a>, and adding admins in <a href="/tutorials/add-admin-by-steamid">the add-admin guide</a>.</p> | |
| 37 | + | |
| 38 | +<h2>5. Fix duplicate IDs while you are here</h2> | |
| 39 | +<p>Spoofing's cousin is collision: many cracked clients ship the same default SteamID, so without generation everyone shares one identity and bans and admin become meaningless. A correct salted Reunion setup gives each client a distinct ID — the same mechanism that stops spoofing also fixes <a href="/tutorials/fix-duplicate-steamids-nonsteam">duplicate SteamIDs</a>.</p> | |
| 40 | + | |
| 41 | +<h2>Troubleshooting</h2> | |
| 42 | +<ul> | |
| 43 | +<li><strong>Reunion will not load</strong> — the salt is shorter than 16 characters, or <code>reunion.cfg</code> is malformed. Lengthen the salt and check the syntax.</li> | |
| 44 | +<li><strong>All admins lost access at once</strong> — you changed <code>SteamIdHashSalt</code>, which regenerated every non-steam ID. Either restore the old salt or re-add admins under the new IDs.</li> | |
| 45 | +<li><strong>An impostor still got admin</strong> — you are authenticating by SteamID only and the salt leaked or the mode trusts client IDs. Move critical admins to password auth.</li> | |
| 46 | +<li><strong>Password admin cannot authenticate</strong> — the client <code>setinfo _pw</code> does not match <code>users.ini</code>, or the entry lacks the "authenticate by password" flag. Both sides must agree; see <a href="/tutorials/amxx-cfg-explained">amxx.cfg and the password field</a>.</li> | |
| 47 | +</ul> | |
| 48 | + | |
| 49 | +<h2>Verification</h2> | |
| 50 | +<p>Have a trusted second person connect from a non-steam client and read their ID in <code>status</code> — it must be unique, not shared with anyone else. Then, from a clean test client, deliberately try to present your admin's SteamID: with a strong secret salt and password-authenticated admins, that client must <em>not</em> receive admin flags. Confirm your real admin still authenticates (with the password if you configured one). If any spoof succeeds, treat the salt as compromised, rotate it, and move privileged accounts to password auth.</p> |
reserved-slots-setup/en.md
A
| @@ -0,0 +1,57 @@ | ||
| 1 | +--- | |
| 2 | +title: "Reserved Slots for VIPs and Admins" | |
| 3 | +excerpt: "Configure AMX Mod X reserved slots so admins and VIPs can always get in, hide the reserved slots so the server shows full, and grant access with the b flag." | |
| 4 | +category: "administration" | |
| 5 | +tags: "reserved-slots, vip" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>A popular CS 1.6 server that is always full has a problem: your admins and paying VIPs cannot get in either. Reserved slots fix that — they hold back a few slots that only privileged players can occupy, so a full server still has room for the people who keep it running. AMX Mod X ships this in <code>adminslots.amxx</code>; here is how to set it up and hide the slots cleanly.</p> | |
| 10 | + | |
| 11 | +<h2>1. How reserved slots actually work</h2> | |
| 12 | +<p>Your server has a fixed <code>maxplayers</code> set at startup (e.g. <code>+maxplayers 20</code>). <code>adminslots.amxx</code> carves out the last N of those for players who hold the reservation flag. When a reserved player connects to an otherwise-full server, the plugin either lets them into a held slot or kicks a non-reserved player to make room, depending on configuration. Non-reserved players see the server as full once the public slots are taken.</p> | |
| 13 | + | |
| 14 | +<h2>2. Confirm the plugin is loaded</h2> | |
| 15 | +<p>In <code>addons/amxmodx/configs/plugins.ini</code>:</p> | |
| 16 | +<pre>adminslots.amxx</pre> | |
| 17 | +<p>It ships enabled in a stock <a href="/tutorials/install-amx-mod-x-1-9">AMXX install</a>. Confirm with <code>amxx plugins</code> in the console — it should read <code>running</code>. If not, resolve the load per <a href="/tutorials/plugins-ini-load-order">plugins.ini load order</a>.</p> | |
| 18 | + | |
| 19 | +<h2>3. Set the reservation cvars</h2> | |
| 20 | +<p>Put these in <code>amxx.cfg</code> or <code>server.cfg</code>:</p> | |
| 21 | +<pre>amx_reservation 2 // how many of maxplayers are reserved | |
| 22 | +amx_hideslots 1 // 1 = hide reserved slots (server shows full)</pre> | |
| 23 | +<p>With <code>maxplayers 20</code> and <code>amx_reservation 2</code>, the public sees an 18-slot server; the last two are held for reserved players. This is the arrangement most admins want.</p> | |
| 24 | + | |
| 25 | +<h2>4. Understand amx_hideslots</h2> | |
| 26 | +<p>The <code>amx_hideslots</code> cvar decides whether the reserved slots are visible to the public:</p> | |
| 27 | +<ul> | |
| 28 | +<li><code>0</code> — the slots are visible. The server browser shows 20/20 when full including reserved slots, and a reserved player joining a full server bumps a non-reserved one.</li> | |
| 29 | +<li><code>1</code> — the slots are hidden by lowering the advertised max (via <code>sv_visiblemaxplayers</code>). The public sees 18/18 as "full," so nobody tries for the reserved slots and no kicking is needed — the two slots simply sit invisible until a VIP takes one.</li> | |
| 30 | +</ul> | |
| 31 | +<p>Hiding (<code>1</code>) is the cleaner behavior: nobody gets kicked, and VIPs quietly always fit. Verify with the <code>sv_visiblemaxplayers</code> cvar, which the plugin sets on your behalf when hiding is on.</p> | |
| 32 | + | |
| 33 | +<h2>5. Grant the reservation flag</h2> | |
| 34 | +<p>Reserved access is the <code>b</code> flag in <code>addons/amxmodx/configs/users.ini</code>. Any admin who already has a flag string just needs <code>b</code> included; a VIP who is not otherwise an admin gets <em>only</em> <code>b</code>:</p> | |
| 35 | +<pre>; VIP — reserved slot only, no admin powers | |
| 36 | +"STEAM_0:1:2001" "" "b" "ce" | |
| 37 | + | |
| 38 | +; Admin who should also skip the queue | |
| 39 | +"STEAM_0:1:2002" "" "abcdefiju" "ce"</pre> | |
| 40 | +<p>Account flag <code>c</code> marks the entry as a SteamID and <code>e</code> as name-only auth — the same format used throughout the <a href="/tutorials/prevent-admin-abuse">admin flags guide</a>. Give VIPs only <code>b</code>; there is no reason a paying player needs kick or ban rights. After editing, reload:</p> | |
| 41 | +<pre>amx_reloadadmins</pre> | |
| 42 | +<p>For a full VIP feature set (skins, extra money, a shop) beyond just a slot, layer a <a href="/plugins/csb-vip-core">CSB VIP Core</a> plugin on top; reserved slots are just the entry ticket.</p> | |
| 43 | + | |
| 44 | +<h2>Troubleshooting</h2> | |
| 45 | +<ul> | |
| 46 | +<li><strong>VIPs still cannot join a full server</strong> — <code>amx_reservation</code> is 0, or the player's <code>users.ini</code> entry lacks the <code>b</code> flag, or admins were not reloaded. Check all three.</li> | |
| 47 | +<li><strong>Server shows the wrong player count</strong> — with <code>amx_hideslots 1</code> the advertised max drops by the reservation count; that is expected. Confirm <code>sv_visiblemaxplayers</code>.</li> | |
| 48 | +<li><strong>Non-reserved players get kicked</strong> — <code>amx_hideslots 0</code> lets reserved players bump others. Set it to <code>1</code> to hide the slots instead.</li> | |
| 49 | +<li><strong>Reservation ignored entirely</strong> — <code>adminslots.amxx</code> is not running, or an entry authenticates by name only and the name does not match. Prefer SteamID auth.</li> | |
| 50 | +<li><strong>Everyone counts as reserved</strong> — the <code>b</code> flag leaked in via <code>amx_default_access</code> in <a href="/tutorials/amxx-cfg-explained">amxx.cfg</a>; it must be empty.</li> | |
| 51 | +</ul> | |
| 52 | + | |
| 53 | +<h2>Verification</h2> | |
| 54 | +<p>A practical sizing note: reserve only what you actually need. On a 20-slot server, two reserved slots is plenty for a small admin team; reserving five would advertise the server as 15 slots and cost you real population for VIPs who rarely all show up at once. Match the reservation count to how many privileged players are typically online together, not to your total admin roster.</p> | |
| 55 | +<p>Fill the public slots with bots or test clients until the browser shows the server full, then connect from a client whose SteamID has the <code>b</code> flag — it should get in when a non-reserved client cannot. Read the advertised max back:</p> | |
| 56 | +<pre>sv_visiblemaxplayers // = maxplayers minus amx_reservation when hiding</pre> | |
| 57 | +<p>Confirm the number matches <code>maxplayers</code> minus your reservation. When a flagged client joins a "full" server and an unflagged one is refused, reserved slots are working.</p> | |
| 0 | 58 |









