Signals is a small extension that enables setting sigaction handlers for Linux signals and linking a SourceMod callback to them. To give you a brief introduction, signals are a form of inter-process communication in Linux, mostly fired by the OS but which can be triggered manually and intercepted per-process. I use this myself to make systemd restart and start/stop scripts integrate more fluidly with the server I'm hosting, but you could also use it to call for information dumps from your server. Moreso, with signals, you can have accurately timed events that don't depend on the game server's sense of time and tick rate.
I'm working on a few more essential features so this is not the final release.
This is also my first extension and all kinds of feedback is much appreciated!
Examples (TF2)
Refreshing the map
Often times when your server is running the same map for long periods of time (2+ hours), things start to get jittery. To fix this you could create a plugin with a timer that reloads the map. However, timers wouldn't work on hibernating servers unless you wake the server up. mp_timelimit would not start running (or doesn't work in all game modes) either until the first player has joined after a server (re)start.
With signals you can achieve the same results as other mapchooser plugins. However you can control this behavior from outside the server.
crontab:
PHP Code:
# reload the map every two hours 0 */2 * * * /bin/kill -s SIGWINCH $(pidof srcds_linux)
signals-example.sp:
PHP Code:
#define SHUTDOWNDELAY 60
public void OnPluginStart() { // SIGWINCH is ignored by default so we can repurpose it. SetSignalCallback(WINCH, ReloadMap); }
Action ReloadMap() { LogMessage("Reloading the map in %i seconds", SHUTDOWNDELAY);
if (!GetClientCount(true)) // zero players in server { LogMessage("No clients in-game, reloading instantly");
char CurrentMap[64]; GetCurrentMap(CurrentMap, sizeof(CurrentMap)); ForceChangeLevel(CurrentMap, "Map reload for maintenance");
ForceRoundTimer(SHUTDOWNDELAY); // make a visible countdown to the users with announcer voices
CreateTimer(SHUTDOWNDELAY + 1.0, GameEnd); // stagger them a bit to make the user experience more fluid CreateTimer(SHUTDOWNDELAY + 10.0, ChangeLevel);
PrintToChatAll("[SERVER] Reloading the map in %i seconds for maintenance", SHUTDOWNDELAY);
if (EndGameEnt < 1) EndGameEnt = CreateEntityByName("game_end");
if (IsValidEntity(EndGameEnt)) { AcceptEntityInput(EndGameEnt, "EndGame"); } else // just shutdown instantly { LogError("Couldn't create game_end entity. Shutting down"); InstantShutdown(); }
return Plugin_Continue; }
Toggling VProf profiler
If you want to know how your server is performing at random times, or automate the process of information gathering, you could add two callbacks, one to start the profiler and one to stop it.
signals-example.sp:
PHP Code:
#define MAXCMDLEN 256 DataPack cmds;
public void OnPluginStart() { cmds = CreateDataPack();
// start and stop profiling. SIGUSR1 and SIGUSR2 exist for user defined signals. SetSignalCallback(USR1, StartVProf); SetSignalCallback(USR2, StopVProf); }
// Have to execute the commands in some intervals to get it to dump // stuff into the logfile. Doesn't seem to work any other way. CreateTimer(0.4, ExecuteCmdDelay, cmds); CreateTimer(0.8, ExecuteCmdDelay, cmds); CreateTimer(1.2, ExecuteCmdDelay, cmds); }
Full examples are included in the zip file and downloads.
N.B. The extension was built with a newer version of GLIBCXX than is provided in mp-sdk2013. Make sure your system has the latest libstdc++6 installed and then rename the library in .../mp-sdk2013/bin/libstdc++.so.6 to something else so it doesn't get looked up.