public static void Master_Heartbeat() { string @string; int i; // pgm post3.19 change, cvar pointer not validated before dereferencing if (Globals.dedicated == null || 0 == Globals.dedicated.value) { return; // only dedicated servers send heartbeats } // pgm post3.19 change, cvar pointer not validated before dereferencing if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value) { return; // a private dedicated game } // check for time wraparound if (SV_INIT.svs.last_heartbeat > SV_INIT.svs.realtime) { SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime; } if (SV_INIT.svs.realtime - SV_INIT.svs.last_heartbeat < SV_MAIN.HEARTBEAT_SECONDS * 1000) { return; // not time to send yet } SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime; // send the same string that we would give for a status OOB command @string = SV_MAIN.SV_StatusString(); // send to group master for (i = 0; i < Defines.MAX_MASTERS; i++) { if (SV_MAIN.master_adr[i].port != 0) { Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\n"); Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "heartbeat\n" + @string); } } }
/** * Responds with all the info that qplug or qspy can see */ public static void SVC_Status() { Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "print\n" + SV_MAIN.SV_StatusString()); }