Plugins: Added a callback for when a client is done connecting to a server
This commit is contained in:
parent
23edd47438
commit
ce2185ff02
4 changed files with 119 additions and 33 deletions
|
@ -83,6 +83,8 @@ int g_dmg_iHitBody;
|
||||||
int g_dmg_iFlags;
|
int g_dmg_iFlags;
|
||||||
int g_dmg_iWeapon;
|
int g_dmg_iWeapon;
|
||||||
|
|
||||||
|
var int g_ents_initialized = FALSE;
|
||||||
|
|
||||||
/* main is a qcc leftover */
|
/* main is a qcc leftover */
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,14 +21,19 @@ StartFrame
|
||||||
Called once every single frame.
|
Called once every single frame.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void StartFrame(void)
|
void
|
||||||
|
StartFrame(void)
|
||||||
{
|
{
|
||||||
|
/* For entity parenting to work, we need to go through and run on every
|
||||||
|
* this method on every CBaseEntity class */
|
||||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||||
CBaseEntity ent = (CBaseEntity)a;
|
CBaseEntity ent = (CBaseEntity)a;
|
||||||
ent.ParentUpdate();
|
ent.ParentUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
g_grMode.FrameStart();
|
if (g_ents_initialized)
|
||||||
|
g_grMode.FrameStart();
|
||||||
|
|
||||||
Vote_Frame();
|
Vote_Frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +48,8 @@ loading or receiving packets.
|
||||||
The 'self' global is the connecting client in question.
|
The 'self' global is the connecting client in question.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ClientConnect(float csqc_active)
|
void
|
||||||
|
ClientConnect(float csqc_active)
|
||||||
{
|
{
|
||||||
int playercount = 0;
|
int playercount = 0;
|
||||||
|
|
||||||
|
@ -58,11 +64,13 @@ void ClientConnect(float csqc_active)
|
||||||
spawnfunc_player();
|
spawnfunc_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
g_grMode.PlayerConnect((base_player)self);
|
if (g_ents_initialized)
|
||||||
|
g_grMode.PlayerConnect((base_player)self);
|
||||||
|
|
||||||
for (entity a = world; (a = find(a, ::classname, "player"));)
|
for (entity a = world; (a = find(a, ::classname, "player"));)
|
||||||
playercount++;
|
playercount++;
|
||||||
|
|
||||||
/* we're the only one. respawn all entities */
|
/* we're the only one. respawn all entities */
|
||||||
if (playercount == 1) {
|
if (playercount == 1) {
|
||||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||||
CBaseEntity caw = (CBaseEntity)a;
|
CBaseEntity caw = (CBaseEntity)a;
|
||||||
|
@ -81,9 +89,11 @@ client slot referred to by the 'self' global will be cleared.
|
||||||
This means the fields will still be accessible inside of this function.
|
This means the fields will still be accessible inside of this function.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ClientDisconnect(void)
|
void
|
||||||
|
ClientDisconnect(void)
|
||||||
{
|
{
|
||||||
g_grMode.PlayerDisconnect((base_player)self);
|
if (g_ents_initialized)
|
||||||
|
g_grMode.PlayerDisconnect((base_player)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -94,9 +104,11 @@ Called by the 'kill' command.
|
||||||
The 'self' global is the client issueing the command.
|
The 'self' global is the client issueing the command.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void ClientKill(void)
|
void
|
||||||
|
ClientKill(void)
|
||||||
{
|
{
|
||||||
g_grMode.PlayerKill((base_player)self);
|
if (g_ents_initialized)
|
||||||
|
g_grMode.PlayerKill((base_player)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -107,7 +119,8 @@ Run every frame on every spectator.
|
||||||
The 'self' global refers to one of any given amount of spectators.
|
The 'self' global refers to one of any given amount of spectators.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void SpectatorThink(void)
|
void
|
||||||
|
SpectatorThink(void)
|
||||||
{
|
{
|
||||||
Game_SpectatorThink();
|
Game_SpectatorThink();
|
||||||
}
|
}
|
||||||
|
@ -120,7 +133,8 @@ Called when a spectator joins the server.
|
||||||
The 'self' global is the connecting spectator in question.
|
The 'self' global is the connecting spectator in question.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void SpectatorConnect(void)
|
void
|
||||||
|
SpectatorConnect(void)
|
||||||
{
|
{
|
||||||
Game_SpectatorConnect();
|
Game_SpectatorConnect();
|
||||||
}
|
}
|
||||||
|
@ -134,7 +148,8 @@ The 'self' global is the leaving spectator in question.
|
||||||
Attributes cleared when this function is done executing.
|
Attributes cleared when this function is done executing.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void SpectatorDisconnect(void)
|
void
|
||||||
|
SpectatorDisconnect(void)
|
||||||
{
|
{
|
||||||
Game_SpectatorDisconnect();
|
Game_SpectatorDisconnect();
|
||||||
}
|
}
|
||||||
|
@ -150,9 +165,13 @@ The 'parmX' globals are also populated with any data carried over from
|
||||||
past levels for the player in question.
|
past levels for the player in question.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void PutClientInServer(void)
|
void
|
||||||
|
PutClientInServer(void)
|
||||||
{
|
{
|
||||||
g_grMode.PlayerSpawn((base_player)self);
|
if (g_ents_initialized)
|
||||||
|
g_grMode.PlayerSpawn((base_player)self);
|
||||||
|
|
||||||
|
Plugin_PlayerEntered((base_player)self);
|
||||||
|
|
||||||
/* activate all game_playerspawn entities */
|
/* activate all game_playerspawn entities */
|
||||||
for (entity a = world; (a = find(a, ::targetname, "game_playerspawn"));) {
|
for (entity a = world; (a = find(a, ::targetname, "game_playerspawn"));) {
|
||||||
|
@ -172,7 +191,8 @@ The 'self' global refers to a single client, as this function is called
|
||||||
times the amount of players in a given game.
|
times the amount of players in a given game.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void PlayerPreThink(void)
|
void
|
||||||
|
PlayerPreThink(void)
|
||||||
{
|
{
|
||||||
if (self.classname != "player") {
|
if (self.classname != "player") {
|
||||||
return;
|
return;
|
||||||
|
@ -184,7 +204,8 @@ void PlayerPreThink(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_grMode.PlayerPreFrame((base_player)self);
|
if (g_ents_initialized)
|
||||||
|
g_grMode.PlayerPreFrame((base_player)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -196,7 +217,8 @@ The 'self' global refers to a single client, as this function is called
|
||||||
times the amount of players in a given game.
|
times the amount of players in a given game.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void PlayerPostThink(void)
|
void
|
||||||
|
PlayerPostThink(void)
|
||||||
{
|
{
|
||||||
if (self.classname != "player") {
|
if (self.classname != "player") {
|
||||||
return;
|
return;
|
||||||
|
@ -208,7 +230,8 @@ void PlayerPostThink(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_grMode.PlayerPostFrame((base_player)self);
|
if (g_ents_initialized)
|
||||||
|
g_grMode.PlayerPostFrame((base_player)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -220,10 +243,13 @@ change ever having taken place.
|
||||||
The 'self' global does not refer to anything.
|
The 'self' global does not refer to anything.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void SetNewParms(void)
|
void
|
||||||
|
SetNewParms(void)
|
||||||
{
|
{
|
||||||
iprint("Setting New Level Parameters");
|
iprint("Setting New Level Parameters");
|
||||||
g_grMode.LevelNewParms();
|
|
||||||
|
if (g_ents_initialized)
|
||||||
|
g_grMode.LevelNewParms();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -238,10 +264,13 @@ Make sure we're saving important fields/attributes in the 'parmX' globals
|
||||||
allocated for every client.
|
allocated for every client.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void SetChangeParms(void)
|
void
|
||||||
|
SetChangeParms(void)
|
||||||
{
|
{
|
||||||
iprint("Setting Level-Change Parameters");
|
iprint("Setting Level-Change Parameters");
|
||||||
g_grMode.LevelChangeParms((base_player)self);
|
|
||||||
|
if (g_ents_initialized)
|
||||||
|
g_grMode.LevelChangeParms((base_player)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -254,7 +283,8 @@ The 'self' global is the entity having sent the input packet,
|
||||||
with the input_X globals being set to the appropriate data.
|
with the input_X globals being set to the appropriate data.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void SV_RunClientCommand(void)
|
void
|
||||||
|
SV_RunClientCommand(void)
|
||||||
{
|
{
|
||||||
if (self.classname != "player") {
|
if (self.classname != "player") {
|
||||||
return;
|
return;
|
||||||
|
@ -283,7 +313,8 @@ take over, you need to pass the string 'cmd' over via clientcommand().
|
||||||
Notable examples of client cmd's involve the chat system.
|
Notable examples of client cmd's involve the chat system.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void SV_ParseClientCommand(string cmd)
|
void
|
||||||
|
SV_ParseClientCommand(string cmd)
|
||||||
{
|
{
|
||||||
string newcmd = Plugin_ParseClientCommand(cmd);
|
string newcmd = Plugin_ParseClientCommand(cmd);
|
||||||
|
|
||||||
|
@ -300,7 +331,8 @@ init
|
||||||
Called when the QC module gets loaded. No entities exist yet.
|
Called when the QC module gets loaded. No entities exist yet.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void init(float prevprogs)
|
void
|
||||||
|
init(float prevprogs)
|
||||||
{
|
{
|
||||||
iprint("Initializing Server-Module");
|
iprint("Initializing Server-Module");
|
||||||
Plugin_Init();
|
Plugin_Init();
|
||||||
|
@ -314,10 +346,13 @@ Called inside initents() to make sure the entities have their Respawn()
|
||||||
method called at the beginning of them having spawned.
|
method called at the beginning of them having spawned.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void init_respawn(void)
|
void
|
||||||
|
init_respawn(void)
|
||||||
{
|
{
|
||||||
iprint("Respawning Entities");
|
iprint("Respawning Entities");
|
||||||
g_grMode.InitPostEnts();
|
|
||||||
|
if (g_ents_initialized)
|
||||||
|
g_grMode.InitPostEnts();
|
||||||
|
|
||||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||||
CBaseEntity ent = (CBaseEntity)a;
|
CBaseEntity ent = (CBaseEntity)a;
|
||||||
|
@ -333,7 +368,8 @@ initents
|
||||||
???
|
???
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void initents(void)
|
void
|
||||||
|
initents(void)
|
||||||
{
|
{
|
||||||
iprint("Initializing Entities");
|
iprint("Initializing Entities");
|
||||||
|
|
||||||
|
@ -426,6 +462,8 @@ void initents(void)
|
||||||
Plugin_InitEnts();
|
Plugin_InitEnts();
|
||||||
Mapcycle_Init();
|
Mapcycle_Init();
|
||||||
Vote_Init();
|
Vote_Init();
|
||||||
|
|
||||||
|
g_ents_initialized = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -440,7 +478,8 @@ as they do not exist yet. Keep this in mind.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
var int autocvar_sv_levelexec = 1;
|
var int autocvar_sv_levelexec = 1;
|
||||||
void worldspawn(void)
|
void
|
||||||
|
worldspawn(void)
|
||||||
{
|
{
|
||||||
iprint("Initializing World");
|
iprint("Initializing World");
|
||||||
lightstyle(0, "m");
|
lightstyle(0, "m");
|
||||||
|
@ -472,7 +511,8 @@ When returning FALSE the server will interpret the command.
|
||||||
Returning TRUE will mark the command as 'resolved'.
|
Returning TRUE will mark the command as 'resolved'.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
float ConsoleCmd(string cmd)
|
float
|
||||||
|
ConsoleCmd(string cmd)
|
||||||
{
|
{
|
||||||
player pl;
|
player pl;
|
||||||
|
|
||||||
|
@ -488,8 +528,9 @@ float ConsoleCmd(string cmd)
|
||||||
pl = (player)self;
|
pl = (player)self;
|
||||||
|
|
||||||
/* give the game-mode a chance to override us */
|
/* give the game-mode a chance to override us */
|
||||||
if (g_grMode.ConsoleCommand(pl, cmd) == TRUE)
|
if (g_ents_initialized)
|
||||||
return TRUE;
|
if (g_grMode.ConsoleCommand(pl, cmd) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
/* time to handle commands that apply to all games */
|
/* time to handle commands that apply to all games */
|
||||||
tokenize(cmd);
|
tokenize(cmd);
|
||||||
|
@ -506,6 +547,12 @@ float ConsoleCmd(string cmd)
|
||||||
t.Trigger(self, TRIG_TOGGLE);
|
t.Trigger(self, TRIG_TOGGLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "respawn_ents":
|
||||||
|
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||||
|
CBaseEntity ent = (CBaseEntity)a;
|
||||||
|
ent.Respawn();
|
||||||
|
}
|
||||||
|
break;
|
||||||
#ifdef BOT_INCLUDED
|
#ifdef BOT_INCLUDED
|
||||||
case "way":
|
case "way":
|
||||||
Way_Cmd();
|
Way_Cmd();
|
||||||
|
@ -525,7 +572,8 @@ Returns TRUE if the server should pause the game-logic when the 'pause' command
|
||||||
is being executed.
|
is being executed.
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
float SV_ShouldPause(float newstatus)
|
float
|
||||||
|
SV_ShouldPause(float newstatus)
|
||||||
{
|
{
|
||||||
if (serverkeyfloat("background") == 1)
|
if (serverkeyfloat("background") == 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -25,4 +25,5 @@ int Plugin_RunClientCommand(void);
|
||||||
string Plugin_ParseClientCommand(string);
|
string Plugin_ParseClientCommand(string);
|
||||||
int Plugin_PlayerConnect(base_player);
|
int Plugin_PlayerConnect(base_player);
|
||||||
int Plugin_PlayerDisconnect(base_player);
|
int Plugin_PlayerDisconnect(base_player);
|
||||||
|
int Plugin_PlayerEntered(base_player);
|
||||||
void Plugin_PlayerObituary(entity, entity, int, int, int);
|
void Plugin_PlayerObituary(entity, entity, int, int, int);
|
||||||
|
|
|
@ -264,6 +264,41 @@ Plugin_PlayerDisconnect(base_player cl)
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Plugin_PlayerEntered
|
||||||
|
|
||||||
|
Called when a player has fully connected and entered the server
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
Plugin_PlayerEntered(base_player cl)
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
int tval;
|
||||||
|
int(entity) vFunc;
|
||||||
|
|
||||||
|
if (g_plugins_enabled == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* rval = final return value, tval = temporary return value.
|
||||||
|
if at least one of the plugins returns TRUE, then RunClientCommand
|
||||||
|
will not be called by the engine, as it should be */
|
||||||
|
rval = FALSE;
|
||||||
|
tval = FALSE;
|
||||||
|
|
||||||
|
for (int i = 0; i < g_plugincount; i++) {
|
||||||
|
vFunc = externvalue(g_plugindb[i].m_flProgsID, "FMX_PlayerEntered");
|
||||||
|
|
||||||
|
if (vFunc) {
|
||||||
|
tval = vFunc(cl);
|
||||||
|
rval |= tval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
Plugin_PlayerObituary
|
Plugin_PlayerObituary
|
||||||
|
|
Loading…
Reference in a new issue