Skip to content

Add Metamod-R timer fallback and static libstdc++ for legacy gamemod ABI#3

Open
APGRoboCop wants to merge 1 commit intomasterfrom
claude/romantic-roentgen-f87e4e
Open

Add Metamod-R timer fallback and static libstdc++ for legacy gamemod ABI#3
APGRoboCop wants to merge 1 commit intomasterfrom
claude/romantic-roentgen-f87e4e

Conversation

@APGRoboCop
Copy link
Copy Markdown
Owner

Summary

  • adminmod_timer fallback for Metamod-R. CREATE_NAMED_ENTITY("adminmod_timer") returns null on Metamod-R because it doesn't expose LINK_ENTITY_TO_PLUGIN; previously this aborted the DLL via am_exit(1) and silently broke every timer-driven say command (timeleft, nextmap, votes). On null we now spin up a free-standing CTimer backed by a static entvars_t and poll its nextthink from AM_StartFrame() instead of relying on the engine to fire it. GetAdminTimer() centralises the lookup so callers don't care which path is active.
  • Static libstdc++/libgcc on Linux. The previous Makefile had -static-libstdc++ on the compile line (no-op with -c) and -nodefaultlibs on the link line (which stripped libstdc++ before anything could re-add it), so the resulting .so dynamically depended on the build host's libstdc++.so.6. That broke loading on pre-SteamPipe gamemod hosts (TS3 3.0, Action Half-Life, FireArms 3.0). Moved the static flags to SHLIBLDFLAGS where they actually take effect, dropped -nodefaultlibs, added -Wl,--no-as-needed, and cleared the malformed STDCPPLIB=-L<path-to-.so> (-L takes a directory).
  • Migrated remaining GET_PRIVATE(pTimerEnt) call sites in admin_commands.cpp (changelevel, kill_timer, get_timer, set_timer, vote_multiple, vote_allowed) to GetAdminTimer() so they work in fallback mode. vote_allowed would otherwise have silently returned 0 forever under Metamod-R.

Why

Reported by a server admin running Metamod-R: AdminMod refuses to load. Independently, the SteamPipe-built Linux .so doesn't load against legacy gamemods (TS3/AHL/FA3), forcing them to stay on AdminMod 2.50.60. Both root causes are addressed here -- the fallback restores Metamod-R support without affecting Metamod-P/-AM (which keep the original entity path), and the static-runtime build matches what AMXX 1.8.2+ does on Linux for cross-host compatibility.

Test plan

  • Build Ometamod target on Linux. Confirm ldd admin_mm_i386.so shows no libstdc++.so.6 or libgcc_s.so.1 dependency.
  • Run on a stock HLDS + Metamod-P server: confirm no warning, say timeleft/say nextmap/vote_multiple work as before.
  • Run on a Metamod-R server: confirm console shows WARNING: CREATE_NAMED_ENTITY failed for adminmod_timer; using AM_StartFrame polling fallback, then timer-driven say commands fire correctly.
  • Run on legacy (pre-SteamPipe) gamemod hosts: TS3 3.0, Action Half-Life, FireArms 3.0.
  • Map change with changelevel intermission timer set: confirm the timer survives and fires on the next map.

Reviewer notes

  • The Windows path is unchanged. admin_mod_mm.dll users won't see any behavior change.
  • s_fallbackTimer is a single static instance with module lifetime; AM_Initialize() resets s_bTimerFallbackActive so each map change re-detects whether the entity link is available.
  • The static-libstdc++ approach means C++ exceptions can't propagate across the AdminMod <-> gamemod boundary. AdminMod doesn't currently throw across that boundary, so this is fine, but worth flagging for future code.

🤖 Generated with Claude Code

Two related fixes for SteamPipe/legacy compatibility:

1. adminmod_timer fallback for Metamod-R
   Metamod-R drops LINK_ENTITY_TO_PLUGIN, so CREATE_NAMED_ENTITY("adminmod_timer")
   in AM_ClientStart() returns null and the previous code aborted via am_exit(1).
   Without the timer, all timer-driven say commands (timeleft, nextmap, votes)
   silently die.

   On null entity creation we now spin up a free-standing CTimer instance backed
   by a static entvars_t, set s_bTimerFallbackActive = true, and poll its
   nextthink from AM_StartFrame() instead of relying on the engine to fire it.
   GetAdminTimer() centralises the lookup so callers don't care which path is
   active. State is reset in AM_Initialize() so map changes can re-detect.

   Also migrated the remaining direct GET_PRIVATE(pTimerEnt) call sites in
   admin_commands.cpp (changelevel, kill_timer, get_timer, set_timer,
   vote_multiple, vote_allowed) to use GetAdminTimer() so they work in both
   modes.

2. Static libstdc++/libgcc in the Linux Makefile
   The previous flags had -static-libstdc++ on the compile line (no-op with -c)
   and -nodefaultlibs on the link line (which stripped libstdc++ before anything
   could re-add it), so the resulting .so dynamically depended on the build
   host's libstdc++.so.6. That broke loading on pre-SteamPipe gamemod hosts
   (TS3 3.0, Action Half-Life, FireArms 3.0) whose runtime is older than
   the build machine.

   Moved -static-libstdc++ -static-libgcc to SHLIBLDFLAGS where they actually
   take effect, dropped -nodefaultlibs, and added -Wl,--no-as-needed. Cleared
   the malformed STDCPPLIB=-L<path-to-.so> (the -L flag takes a directory).
   Result: ldd on the .so should show no libstdc++/libgcc dependency, matching
   what AMXX 1.8.2+ does on Linux.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant