// Removes a player from a team. void G_refRemove_cmd(gentity_t *ent) { int pid; char arg[MAX_TOKEN_CHARS]; gentity_t *player; // Works for teamplayish matches if(g_gametype.integer < GT_WOLF) { G_refPrintf(ent, "\"remove\" only for team-based games!"); return; } // Find the player to remove. trap_Argv(2, arg, sizeof(arg)); if((pid = ClientNumberFromString(ent, arg)) == -1) return; player = g_entities + pid; // Can only remove active players. if(player->client->sess.sessionTeam == TEAM_SPECTATOR) { G_refPrintf(ent, "You can only remove people in the game!"); return; } // Announce the removal AP(va("cp \"%s\n^7removed from team %s\n\"", player->client->pers.netname, aTeams[player->client->sess.sessionTeam])); CPx(pid, va("print \"^5You've been removed from the %s team\n\"", aTeams[player->client->sess.sessionTeam])); SetTeam( player, "s", qtrue, -1, -1, qfalse ); if(g_gamestate.integer == GS_WARMUP || g_gamestate.integer == GS_WARMUP_COUNTDOWN) { G_readyMatchState(); } }
void Cmd_Jail_f(gentity_t *ent) { char buffer[MAX_TOKEN_CHARS]; int clientNum; if (!HasPermission(ent, PERMISSION_JAIL)) return; if (trap_Argc() != 2) { MM_SendMessage(ent - g_entities, va("print \"Command usage: mjail <client-name-or-number>\n\"")); return; } trap_Argv(1, buffer, sizeof(buffer)); clientNum = ClientNumberFromString(ent, buffer); if (clientNum == -1) { MM_SendMessage(ent - g_entities, va("print \"ERROR: Could not identify player %s\n\"", buffer)); return; } gentity_t *target = &g_entities[clientNum]; if (target->client->sess.jailed == qfalse) MM_JailClient(target, qfalse); else { target->client->sess.jailed = qfalse; ClientSpawn(target); // not sure how safe this is but what the heck lmao } }
static void Cmd_Tell_f( gentity_t *ent ) { int targetNum; gentity_t *target; char *p, arg[MAX_TOKEN_CHARS]; if ( trap->Cmd_Argc() < 2 ) return; trap->Cmd_Argv( 1, arg, sizeof( arg ) ); targetNum = ClientNumberFromString( ent, arg ); if ( targetNum == -1 ) return; target = &g_entities[targetNum]; if ( !target || !target->inuse || !target->client ) return; p = ConcatArgs( 2 ); //Raz: BOF if ( strlen( p ) > MAX_SAY_TEXT ) { p[MAX_SAY_TEXT-1] = '\0'; G_LogPrintf( "Cmd_Tell_f from %d (%s) has been truncated: %s\n", ent->s.number, ent->client->pers.netname, p ); } G_LogPrintf( "tell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, p ); G_Say( ent, target, SAY_TELL, p ); // don't tell to the player self if it was already directed to this player // also don't send the chat back to a bot if ( ent != target && !(ent->r.svFlags & SVF_BOT) ) G_Say( ent, ent, SAY_TELL, p ); }
/* ================== Cmd_VoiceTell_f ================== */ static void Cmd_VoiceTell_f( gentity_t *ent, qboolean voiceonly ) { int targetNum; gentity_t *target; char *id; char arg[MAX_TOKEN_CHARS]; if ( trap_Argc () < 3 ) { trap_SendServerCommand( ent-g_entities, va( "print \"Usage: %s <player id> <voice id>\n\"", voiceonly ? "votell" : "vtell" ) ); return; } trap_Argv( 1, arg, sizeof( arg ) ); targetNum = ClientNumberFromString( ent, arg ); if ( targetNum == -1 ) { return; } target = &g_entities[targetNum]; if ( !target->inuse || !target->client ) { return; } id = ConcatArgs( 2 ); G_LogPrintf( "vtell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, id ); G_Voice( ent, target, SAY_TELL, id, voiceonly ); // don't tell to the player self if it was already directed to this player // also don't send the chat back to a bot if ( ent != target && !(ent->r.svFlags & SVF_BOT)) { G_Voice( ent, ent, SAY_TELL, id, voiceonly ); } }
// Sends a player's stats to the requesting client. void G_statsPrint( gentity_t *ent, int nType ) { int pid; char *cmd = ( nType == 0 ) ? "ws" : ( ( nType == 1 ) ? "wws" : "gstats" ); // Yes, not the cleanest char arg[MAX_TOKEN_CHARS]; if ( !ent || ( ent->r.svFlags & SVF_BOT ) ) { return; } // If requesting stats for self, its easy. if ( trap_Argc() < 2 ) { if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) { CP( va( "%s %s\n", cmd, G_createStats( ent ) ) ); // Specs default to players they are chasing } else if ( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) { CP( va( "%s %s\n", cmd, G_createStats( g_entities + ent->client->sess.spectatorClient ) ) ); } else { CP( "cpm \"Type ^3\\stats <player_id>^7 to see stats on an active player.\n\"" ); return; } } else { // Find the player to poll stats. trap_Argv( 1, arg, sizeof( arg ) ); if ( ( pid = ClientNumberFromString( ent, arg ) ) == -1 ) { return; } CP( va( "%s %s\n", cmd, G_createStats( g_entities + pid ) ) ); } }
void Svcmd_GiveAdmin_f ( void ) { int client_id = -1; char arg1[MAX_STRING_CHARS]; if (trap->Argc() != 2) { trap->Print( "Usage: giveadmin <player>\n"); return; } trap->Argv( 1, arg1, sizeof( arg1 ) ); client_id = ClientNumberFromString( NULL, arg1, qfalse ); if (client_id == -1) { return; } if (g_entities[client_id].client->sess.amrpgmode > 0) { g_entities[client_id].client->pers.bitvalue |= (1 << ADM_GIVEADM); save_account(&g_entities[client_id]); trap->Print("GiveAdmin saved successfully.\n"); } else { trap->Print("Player is not logged in.\n"); } }
/* ================== Cmd_Tell_f ================== */ static void Cmd_Tell_f( gentity_t *ent ) { int targetNum; gentity_t *target; char *p; char arg[MAX_TOKEN_CHARS]; if ( trap_Argc () < 3 ) { trap_SendServerCommand( ent-g_entities, "print \"Usage: tell <player id> <message>\n\"" ); return; } trap_Argv( 1, arg, sizeof( arg ) ); targetNum = ClientNumberFromString( ent, arg ); if ( targetNum == -1 ) { return; } target = &g_entities[targetNum]; if ( !target->inuse || !target->client ) { return; } p = ConcatArgs( 2 ); G_LogPrintf( "tell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, p ); G_Say( ent, target, SAY_TELL, p ); // don't tell to the player self if it was already directed to this player // also don't send the chat back to a bot if ( ent != target && !(ent->r.svFlags & SVF_BOT)) { G_Say( ent, ent, SAY_TELL, p ); } }
// ************** SPECINVITE // // Sends an invitation to a player to spectate a team. void G_specinvite_cmd(gentity_t * ent, unsigned int dwCommand, qboolean fLock) { int tteam, pid; gentity_t *player; char arg[MAX_TOKEN_CHARS]; if(team_nocontrols.integer) { G_noTeamControls(ent); return; } if(!G_cmdDebounce(ent, aCommandInfo[dwCommand].pszCommandName)) { return; } tteam = G_teamID(ent); if(tteam == TEAM_AXIS || tteam == TEAM_ALLIES) { if(!teamInfo[tteam].spec_lock) { CP("cpm \"Your team isn't locked from spectators!\n\""); return; } // Find the player to invite. trap_Argv(1, arg, sizeof(arg)); if((pid = ClientNumberFromString(ent, arg)) == -1) { return; } player = g_entities + pid; // Can't invite self if(player->client == ent->client) { CP("cpm \"You can't specinvite yourself!\n\""); return; } // Can't invite an active player. if(player->client->sess.sessionTeam != TEAM_SPECTATOR) { CP("cpm \"You can't specinvite a non-spectator!\n\""); return; } player->client->sess.spec_invite |= tteam; // Notify sender/recipient CP(va("print \"%s^7 has been sent a spectator invitation.\n\"", player->client->pers.netname)); G_printFull(va("*** You've been invited to spectate the %s team!", aTeams[tteam]), player); } else { CP("cpm \"Spectators can't specinvite players!\n\""); } }
static void Cmd_Follow_f( gentity_t *ent ) { int i; char arg[MAX_TOKEN_CHARS]; if ( trap->Cmd_Argc() != 2 ) { if ( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) { StopFollowing( ent ); } return; } trap->Cmd_Argv( 1, arg, sizeof( arg ) ); i = ClientNumberFromString( ent, arg ); if ( i == -1 ) { return; } // can't follow self if ( &level.clients[ i ] == ent->client ) { return; } // can't follow another spectator if ( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR ) { return; } // first set them to spectator if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) { SetTeam( ent, "spectator" ); } ent->client->sess.spectatorState = SPECTATOR_FOLLOW; ent->client->sess.spectatorClient = i; }
// (Un)Mutes a player void G_refMute_cmd(gentity_t *ent, qboolean mute) { int pid; char arg[MAX_TOKEN_CHARS]; gentity_t *player; // Find the player to mute. trap_Argv(2, arg, sizeof(arg)); if((pid = ClientNumberFromString(ent, arg)) == -1) return; player = g_entities + pid; if( player->client->sess.referee != RL_NONE ) { G_refPrintf(ent, "Cannot mute a referee.\n" ); return; } if(player->client->sess.muted == mute) { G_refPrintf(ent, "\"%s^*\" %s\n", player->client->pers.netname, mute ? "is already muted!" : "is not muted!" ); return; } if( mute ) { CPx(pid, "print \"^5You've been muted\n\"" ); player->client->sess.muted = qtrue; G_Printf( "\"%s^*\" has been muted\n", player->client->pers.netname ); ClientUserinfoChanged( pid ); } else { CPx(pid, "print \"^5You've been unmuted\n\"" ); player->client->sess.muted = qfalse; G_Printf( "\"%s^*\" has been unmuted\n", player->client->pers.netname ); ClientUserinfoChanged( pid ); } }
/* LQ3A: Added eType variable. See LQ3A_FOLLOW_TYPE_* definitions for usage. */ void Cmd_Follow_f(gentity_t *ent, lq3a_follow_type_t eType) { int i; char arg[MAX_TOKEN_CHARS]; if ( trap_Argc() != 2 ) { /* LQ3A */ if ((ent->client->sess.spectatorState == SPECTATOR_FOLLOW) || (ent->client->sess.spectatorState == SPECTATOR_FOLLOW_THIRDPERSON)) { StopFollowing( ent ); } return; } trap_Argv( 1, arg, sizeof( arg ) ); i = ClientNumberFromString( ent, arg ); if ( i == -1 ) { return; } // can't follow self if ( &level.clients[ i ] == ent->client ) { return; } // can't follow another spectator if ( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR ) { return; } // if they are playing a tournement game, count as a loss if ( (g_gametype.integer == GT_TOURNAMENT ) && ent->client->sess.sessionTeam == TEAM_FREE ) { ent->client->sess.losses++; } // first set them to spectator if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) { /* LQ3A */ SetTeam(ent, "spectator", qtrue); } /* LQ3A */ switch (eType) { case LQ3A_FOLLOW_TYPE_THIRDPERSON: ent->client->sess.spectatorState = SPECTATOR_FOLLOW_THIRDPERSON; break; // case LQ3A_FOLLOW_AUTO: // case LQ3A_FOLLOW_TYPE_FIRSTPERSON: default: ent->client->sess.spectatorState = SPECTATOR_FOLLOW; break; } ent->client->sess.spectatorClient = i; }
// *** Player Un-Mute *** int G_UnMute_v(gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd) { if (fRefereeCmd) { // handled elsewhere return G_NOTFOUND; } // Vote request (vote is being initiated) if (arg) { int pid; if (!vote_allow_muting.integer && ent && !ent->client->sess.referee) { G_voteDisableMessage(ent, arg); return G_INVALID; } else if (G_voteDescription(ent, fRefereeCmd, dwVoteIndex)) { return G_INVALID; } else if ((pid = ClientNumberFromString(ent, arg2)) == -1) { return G_INVALID; } if (!level.clients[pid].sess.muted) { G_refPrintf(ent, "Player is not muted!"); return G_INVALID; } Com_sprintf(level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid); Com_sprintf(arg2, VOTE_MAXSTRING, "%s", level.clients[pid].pers.netname); // Vote action (vote has passed) } else { int pid = atoi(level.voteInfo.vote_value); // Mute a player if (level.clients[pid].sess.referee != RL_RCON) { trap_SendServerCommand(pid, va("cpm \"^3You have been un-muted\"")); level.clients[pid].sess.muted = qfalse; AP(va("cp \"%s\n^3has been un-muted!\n\"", level.clients[pid].pers.netname)); ClientUserinfoChanged(pid); } else { G_Printf("Cannot un-mute a referee.\n"); } } return G_OK; }
// *** Player Kick *** int G_Kick_v(gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd) { // Vote request (vote is being initiated) if (arg) { int pid; if (!vote_allow_kick.integer && ent && !ent->client->sess.referee) { G_voteDisableMessage(ent, arg); return G_INVALID; } else if (G_voteDescription(ent, fRefereeCmd, dwVoteIndex)) { return G_INVALID; } else if ((pid = ClientNumberFromString(ent, arg2)) == -1) { return G_INVALID; } if (level.clients[pid].sess.referee) { G_refPrintf(ent, "Can't vote to kick referees!"); return G_INVALID; } if (g_entities[pid].r.svFlags & SVF_BOT) { G_refPrintf(ent, "Can't vote to kick bots!"); return G_INVALID; } if (!fRefereeCmd && ent) { if (level.clients[pid].sess.sessionTeam != TEAM_SPECTATOR && level.clients[pid].sess.sessionTeam != ent->client->sess.sessionTeam) { G_refPrintf(ent, "Can't vote to kick players on opposing team!"); return G_INVALID; } } Com_sprintf(level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid); Com_sprintf(arg2, VOTE_MAXSTRING, "%s", level.clients[pid].pers.netname); // Vote action (vote has passed) } else { // Kick a player trap_SendConsoleCommand(EXEC_APPEND, va("clientkick %d\n", atoi(level.voteInfo.vote_value))); AP(va("cp \"%s\n^3has been kicked!\n\"", level.clients[atoi(level.voteInfo.vote_value)].pers.netname)); } return G_OK; }
// *** Un-Referee voting *** int G_Unreferee_v(gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd) { // Vote request (vote is being initiated) if(arg) { int pid; if(!vote_allow_referee.integer && ent && !ent->client->sess.referee) { G_voteDisableMessage(ent, arg); return(G_INVALID); } // yada - ent==NULL for console... if( (!ent || ent->client->sess.referee) && trap_Argc() == 2) { G_playersMessage(ent); return(G_INVALID); } else if(ent && trap_Argc() == 2) pid = ent - g_entities; // yada - ent still NULL for console... else if(G_voteDescription(ent, fRefereeCmd, dwVoteIndex)) return(G_INVALID); else if((pid = ClientNumberFromString(ent, arg2)) == -1) return(G_INVALID); if(level.clients[pid].sess.referee == RL_NONE) { G_refPrintf(ent, "[lof]%s [lon]isn't a referee!", level.clients[pid].pers.netname); return(G_INVALID); } if(level.clients[pid].sess.referee == RL_RCON) { G_refPrintf(ent, "[lof]%s's [lon]status cannot be removed", level.clients[pid].pers.netname); return(G_INVALID); } if( level.clients[pid].pers.localClient ) { G_refPrintf(ent, "[lof]%s [lon]^7is the Server Host", level.clients[pid].pers.netname); return(G_INVALID); } Com_sprintf(level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid); Com_sprintf(arg2, VOTE_MAXSTRING, "%s^7", level.clients[pid].pers.netname); // Vote action (vote has passed) } else { // Stripping of referee status gclient_t *cl = &level.clients[atoi(level.voteInfo.vote_value)]; cl->sess.referee = RL_NONE; if( !cl->sess.shoutcaster ) { // don't remove shoutcaster's invitation cl->sess.spec_invite = 0; } AP(va("cp \"%s^7\nis no longer a referee\n\"", cl->pers.netname)); ClientUserinfoChanged( atoi(level.voteInfo.vote_value) ); } return(G_OK); }
// *** Player Kick *** int G_Kick_v( gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd ) { // Vote request (vote is being initiated) if( arg ) { int pid; if( !vote_allow_kick.integer && ent && !ent->client->sess.referee ) { G_voteDisableMessage(ent, arg); return G_INVALID; } else if( G_voteDescription(ent, fRefereeCmd, dwVoteIndex) ) { return G_INVALID; } else if( ( pid = ClientNumberFromString( ent, arg2 ) ) == -1 ) { return G_INVALID; } if( level.clients[ pid ].sess.referee ) { G_refPrintf( ent, "Can't vote to kick referees!" ); return G_INVALID; } if(G_shrubbot_permission(&g_entities[pid], SBF_IMMUNITY)) { G_refPrintf( ent, "Can't vote to kick admins!" ); return G_INVALID; } // pheno: prevent ettv slaves from being callvote kicked if( level.clients[pid].sess.ettv && ( g_ettvFlags.integer & ETTV_IMMUNITY ) ) { G_refPrintf( ent, "Can't vote to kick ettv slaves!" ); return G_INVALID; } if( !fRefereeCmd && ent ) { if( level.clients[ pid ].sess.sessionTeam != TEAM_SPECTATOR && level.clients[ pid ].sess.sessionTeam != ent->client->sess.sessionTeam ) { G_refPrintf( ent, "Can't vote to kick players on opposing team!" ); return G_INVALID; } } Com_sprintf( level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid ); Com_sprintf( arg2, VOTE_MAXSTRING, "%s^7", level.clients[pid].pers.netname ); // Vote action (vote has passed) } else { // Kick a player //trap_SendConsoleCommand( EXEC_APPEND, va( "clientkick %d\n", atoi( level.voteInfo.vote_value ) ) ); // tjw: clientkick doesn't work in 2.60 trap_DropClient(atoi(level.voteInfo.vote_value), "You have been kicked", 120); AP( va( "cp \"%s\n^3has been kicked!\n\"", level.clients[ atoi( level.voteInfo.vote_value ) ].pers.netname ) ); } return G_OK; }
// *** Player PutSpec *** int G_PutSpec_v(gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd) { // yada - my ass... this isnt handled elsewhere at all //if( fRefereeCmd ){ // // handled elsewhere // return(G_NOTFOUND); //} // Vote request (vote is being initiated) if(arg) { int pid; if(!vote_allow_putspec.integer && ent && !ent->client->sess.referee) { G_voteDisableMessage(ent, arg); return(G_INVALID); } else if(G_voteDescription(ent, fRefereeCmd, dwVoteIndex)) return(G_INVALID); else if((pid = ClientNumberFromString(ent, arg2)) == -1) return(G_INVALID); if(level.clients[pid].sess.referee) { G_refPrintf(ent, "Can't vote to PutSpec referees!"); return(G_INVALID); } if(G_shrubbot_permission(&g_entities[pid], SBF_IMMUNITY)) { G_refPrintf( ent, "Can't vote to PutSpec admins!" ); return G_INVALID; } if(level.clients[pid].sess.sessionTeam == TEAM_SPECTATOR || level.clients[pid].sess.sessionTeam != ent->client->sess.sessionTeam) { G_refPrintf(ent, "You can only PutSpec players in your own team!"); return G_INVALID; } Com_sprintf(level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid); Com_sprintf(arg2, VOTE_MAXSTRING, "%s^7", level.clients[pid].pers.netname); // Vote action (vote has passed) } else { int pid = atoi(level.voteInfo.vote_value); SetTeam( &g_entities[pid], "s", qtrue, -1, -1, qfalse ); trap_SendServerCommand( pid, va( "cpm \"^3You have been moved to the Spectators\"") ); AP(va("cp \"%s ^3has been\nmoved to the Spectators!\n\"", level.clients[pid].pers.netname)); ClientUserinfoChanged( pid ); if(g_gamestate.integer == GS_WARMUP || g_gamestate.integer == GS_WARMUP_COUNTDOWN) { G_readyMatchState(); } } return(G_OK); }
// Puts a player on a team. void G_refPlayerPut_cmd( gentity_t *ent, int team_id ) { int pid; char arg[ MAX_TOKEN_CHARS ]; gentity_t *player; // Works for teamplayish matches if ( g_gametype.integer < GT_WOLF ) { G_refPrintf( ent, "\"put[allies|axis]\" only for team-based games!" ); return; } // Find the player to place. trap_Argv( 2, arg, sizeof( arg ) ); if ( ( pid = ClientNumberFromString( ent, arg ) ) == -1 ) { return; } player = g_entities + pid; // Can only move to other teams. if ( player->client->sess.sessionTeam == team_id ) { G_refPrintf( ent, "\"%s\" is already on team %s!", player->client->pers.netname, aTeams[ team_id ] ); // CHRUKER: b047 - Removed unneeded linebreak return; } if ( team_maxplayers.integer && TeamCount( -1, team_id ) >= team_maxplayers.integer ) { G_refPrintf( ent, "Sorry, the %s team is already full!", aTeams[ team_id ] ); // CHRUKER: b047 - Removed unneeded linebreak return; } player->client->pers.invite = team_id; player->client->pers.ready = qfalse; if ( team_id == TEAM_AXIS ) { SetTeam( player, "red", qtrue, -1, -1, qfalse ); } else { SetTeam( player, "blue", qtrue, -1, -1, qfalse ); } if ( g_gamestate.integer == GS_WARMUP || g_gamestate.integer == GS_WARMUP_COUNTDOWN ) { G_readyMatchState(); } }
// *** Player Mute *** int G_Mute_v(gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd) { // yada - no its handled here now //if( fRefereeCmd ) // // handled elsewhere // return(G_NOTFOUND); // Vote request (vote is being initiated) if(arg) { int pid; if(!vote_allow_muting.integer && ent && !ent->client->sess.referee) { G_voteDisableMessage(ent, arg); return(G_INVALID); } else if(G_voteDescription(ent, fRefereeCmd, dwVoteIndex)) return(G_INVALID); else if((pid = ClientNumberFromString(ent, arg2)) == -1) return(G_INVALID); if(level.clients[pid].sess.referee) { G_refPrintf(ent, "Can't vote to mute referees!"); return(G_INVALID); } if(G_shrubbot_permission(&g_entities[pid], SBF_IMMUNITY)) { G_refPrintf( ent, "Can't vote to mute admins!" ); return G_INVALID; } if(level.clients[pid].sess.auto_unmute_time != 0) { G_refPrintf(ent, "Player is already muted!"); return(G_INVALID); } Com_sprintf(level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid); Com_sprintf(arg2, VOTE_MAXSTRING, "%s^7", level.clients[pid].pers.netname); // Vote action (vote has passed) } else { int pid = atoi(level.voteInfo.vote_value); // Mute a player if( level.clients[pid].sess.referee != RL_RCON ) { trap_SendServerCommand( pid, va( "cpm \"^3You have been muted\"") ); level.clients[pid].sess.auto_unmute_time = -1; AP(va("cp \"%s\n^3has been muted!\n\"", level.clients[pid].pers.netname)); ClientUserinfoChanged( pid ); } else { G_Printf( "Cannot mute a referee.\n" ); } } return(G_OK); }
// Puts a player on a team. void G_refPlayerPut_cmd(gentity_t *ent, int team_id) { int pid; char arg[MAX_TOKEN_CHARS]; gentity_t *player; // Works for teamplayish matches if(g_gametype.integer < GT_WOLF) { G_refPrintf(ent, "\"put[allies|axis]\" only for team-based games!"); return; } // yada - yeah right not giving an arg will end up as slot 0... // fixme: could maybe also be handled in ClientNumberFromString // if(ent&&!*s) return ent-g_entities; if(trap_Argc()!=3){ G_refPrintf(ent,"Usage: \\ref put[allies|axis] <pid>"); return; } // Find the player to place. trap_Argv(2, arg, sizeof(arg)); if((pid = ClientNumberFromString(ent, arg)) == -1) return; player = g_entities + pid; // Can only move to other teams. if(player->client->sess.sessionTeam == team_id) { // CHRUKER: b047 - Remove unneeded linebreak G_refPrintf(ent, "\"%s\" is already on team %s!", player->client->pers.netname, aTeams[team_id]); return; } if(team_maxplayers.integer && TeamCount(-1, team_id) >= team_maxplayers.integer) { // CHRUKER: b047 - Remove unneeded linebreak G_refPrintf(ent, "Sorry, the %s team is already full!", aTeams[team_id]); return; } player->client->pers.invite = team_id; player->client->pers.ready = qfalse; if( team_id == TEAM_AXIS ) { SetTeam( player, "red", qtrue, -1, -1, qfalse ); } else { SetTeam( player, "blue", qtrue, -1, -1, qfalse ); } if(g_gamestate.integer == GS_WARMUP || g_gamestate.integer == GS_WARMUP_COUNTDOWN) G_readyMatchState(); }
// *** Referee voting *** int G_Referee_v( gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd ) { // Vote request (vote is being initiated) if ( arg ) { int pid; if ( !vote_allow_referee.integer && ent && !ent->client->sess.referee ) { G_voteDisableMessage( ent, arg ); return( G_INVALID ); } if ( !ent->client->sess.referee && level.numPlayingClients < 3 ) { G_refPrintf( ent, "Sorry, not enough clients in the game to vote for a referee" ); return( G_INVALID ); } if ( ent->client->sess.referee && trap_Argc() == 2 ) { G_playersMessage( ent ); return( G_INVALID ); } else if ( trap_Argc() == 2 ) { pid = ent - g_entities; } else if ( G_voteDescription( ent, fRefereeCmd, dwVoteIndex ) ) { return( G_INVALID ); } else if ( ( pid = ClientNumberFromString( ent, arg2 ) ) == -1 ) { return( G_INVALID ); } if ( level.clients[pid].sess.referee ) { G_refPrintf( ent, "[lof]%s [lon]is already a referee!", level.clients[pid].pers.netname ); return( -1 ); } Com_sprintf( level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid ); Com_sprintf( arg2, VOTE_MAXSTRING, "%s", level.clients[pid].pers.netname ); // Vote action (vote has passed) } else { // Voting in a new referee gclient_t *cl = &level.clients[atoi( level.voteInfo.vote_value )]; if ( cl->pers.connected == CON_DISCONNECTED ) { AP( "print \"Player left before becoming referee\n\"" ); } else { cl->sess.referee = RL_REFEREE; // FIXME: Differentiate voted refs from passworded refs cl->sess.spec_invite = TEAM_AXIS | TEAM_ALLIES; AP( va( "cp \"%s^7 is now a referee\n\"", cl->pers.netname ) ); ClientUserinfoChanged( atoi( level.voteInfo.vote_value ) ); } } return( G_OK ); }
static qboolean G_VoteKick( gentity_t *ent, int numArgs, const char *arg1, const char *arg2 ) { int clientid = ClientNumberFromString( ent, arg2 ); gentity_t *target = NULL; if ( clientid == -1 ) return qfalse; target = &g_entities[clientid]; if ( !target || !target->inuse || !target->client ) return qfalse; Com_sprintf( level.voteString, sizeof( level.voteString ), "clientkick %d", clientid ); Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "kick %s", target->client->pers.netname ); Q_strncpyz( level.voteStringClean, level.voteString, sizeof( level.voteStringClean ) ); return qtrue; }
// (Un)Mutes a player void G_refMute_cmd( gentity_t *ent, qboolean mute ) { int pid; char arg[ MAX_TOKEN_CHARS ]; gentity_t *player; // Find the player to mute. trap_Argv( 2, arg, sizeof( arg ) ); if ( ( pid = ClientNumberFromString( ent, arg ) ) == -1 ) { return; } player = g_entities + pid; // CHRUKER: b060 - Added mute check so that players that are muted before granted referee status, can be unmuted if ( player->client->sess.referee != RL_NONE && mute ) { G_refPrintf( ent, "Cannot mute a referee." ); // CHRUKER: b047 - Removed unneeded linebreak return; } if ( player->client->sess.muted == mute ) { G_refPrintf( ent, "\"%s^*\" %s", player->client->pers.netname, mute ? "is already muted!" : "is not muted!" ); // CHRUKER: b047 - Removed unneeded linebreak return; } if ( mute ) { CPx( pid, "print \"^5You've been muted\n\"" ); player->client->sess.muted = qtrue; G_Printf( "\"%s^*\" has been muted\n", player->client->pers.netname ); ClientUserinfoChanged( pid ); } else { CPx( pid, "print \"^5You've been unmuted\n\"" ); player->client->sess.muted = qfalse; G_Printf( "\"%s^*\" has been unmuted\n", player->client->pers.netname ); ClientUserinfoChanged( pid ); } }
/* ================ G_refMakeShoutcaster_cmd ================ */ void G_refMakeShoutcaster_cmd( gentity_t *ent ) { int pid; char name[MAX_NAME_LENGTH]; gentity_t *player; if( trap_Argc() != 3 ) { G_refPrintf( ent, "Usage: \\ref makeshoutcaster <pid>" ); return; } if( !G_IsShoutcastPasswordSet() ) { G_refPrintf( ent, "Sorry, shoutcaster status disabled on this server." ); return; } trap_Argv( 2, name, sizeof( name ) ); if( ( pid = ClientNumberFromString( ent, name ) ) == -1 ) { return; } player = g_entities + pid; if( !player || !player->client ) { return; } // ignore bots if( player->r.svFlags & SVF_BOT ) { G_refPrintf( ent, "Sorry, a bot can not be a shoutcaster." ); return; } if( player->client->sess.shoutcaster ) { G_refPrintf( ent, "Sorry, %s^7 is already a shoutcaster.", player->client->pers.netname ); return; } G_MakeShoutcaster( player ); }
/* ================= Cmd_Follow_f ================= */ void Cmd_Follow_f( gentity_t *ent ) { int i; char arg[MAX_TOKEN_CHARS]; if ( trap_Argc() != 2 ) { if ( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) { StopFollowing( ent ); } return; } trap_Argv( 1, arg, sizeof( arg ) ); i = ClientNumberFromString( ent, arg ); if ( i == -1 ) { return; } // can't follow self if ( &level.clients[ i ] == ent->client ) { return; } // can't follow another spectator if ( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR ) { return; } // if they are playing a tournement game, count as a loss if ( (g_gametype.integer == GT_TOURNAMENT ) && ent->client->sess.sessionTeam == TEAM_FREE ) { ent->client->sess.losses++; } // first set them to spectator if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) { SetTeam( ent, "spectator" ); } ent->client->sess.spectatorState = SPECTATOR_FOLLOW; ent->client->sess.spectatorClient = i; }
void Cmd_GameCommand_f( gentity_t *ent ) { int targetNum; gentity_t *target; int order; char arg[MAX_TOKEN_CHARS]; if ( trap_Argc() != 3 ) { trap_SendServerCommand( ent-g_entities, va( "print \"Usage: gc <player id> <order 0-%d>\n\"", numgc_orders - 1 ) ); return; } trap_Argv( 2, arg, sizeof( arg ) ); order = atoi( arg ); if ( order < 0 || order >= numgc_orders ) { trap_SendServerCommand( ent-g_entities, va("print \"Bad order: %i\n\"", order)); return; } trap_Argv( 1, arg, sizeof( arg ) ); targetNum = ClientNumberFromString( ent, arg ); if ( targetNum == -1 ) { return; } target = &g_entities[targetNum]; if ( !target->inuse || !target->client ) { return; } G_LogPrintf( "tell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, gc_orders[order] ); G_Say( ent, target, SAY_TELL, gc_orders[order] ); // don't tell to the player self if it was already directed to this player // also don't send the chat back to a bot if ( ent != target && !(ent->r.svFlags & SVF_BOT)) { G_Say( ent, ent, SAY_TELL, gc_orders[order] ); } }
/* ================ G_refRemoveShoutcaster_cmd ================ */ void G_refRemoveShoutcaster_cmd( gentity_t *ent ) { int pid; char name[MAX_NAME_LENGTH]; gentity_t *player; if( trap_Argc() != 3 ) { G_refPrintf( ent, "Usage: \\ref removeshoutcaster <pid>" ); return; } if( !G_IsShoutcastPasswordSet() ) { G_refPrintf( ent, "Sorry, shoutcaster status disabled on this server." ); return; } trap_Argv( 2, name, sizeof( name ) ); if( ( pid = ClientNumberFromString( ent, name ) ) == -1 ) { return; } player = g_entities + pid; if( !player || !player->client ) { return; } if( !player->client->sess.shoutcaster ) { G_refPrintf( ent, "Sorry, %s^7 is not a shoutcaster.", player->client->pers.netname ); return; } G_RemoveShoutcaster( player ); }
/* ================== Cmd_CallVote_f ================== */ void Cmd_CallVote_f( gentity_t *ent ) { char* c; int i; char arg1[MAX_STRING_TOKENS]; char arg2[MAX_STRING_TOKENS]; if ( !g_allowVote.integer ) { trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here.\n\"" ); return; } if ( level.voteTime ) { trap_SendServerCommand( ent-g_entities, "print \"A vote is already in progress.\n\"" ); return; } if ( ent->client->pers.voteCount >= MAX_VOTE_COUNT ) { trap_SendServerCommand( ent-g_entities, "print \"You have called the maximum number of votes.\n\"" ); return; } if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) { trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator.\n\"" ); return; } // make sure it is a valid command to vote on trap_Argv( 1, arg1, sizeof( arg1 ) ); trap_Argv( 2, arg2, sizeof( arg2 ) ); // check for command separators in arg2 for( c = arg2; *c; ++c) { switch(*c) { case '\n': case '\r': case ';': trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" ); return; break; } } if ( !Q_stricmp( arg1, "map_restart" ) ) { } else if ( !Q_stricmp( arg1, "nextmap" ) ) { } else if ( !Q_stricmp( arg1, "map" ) ) { } else if ( !Q_stricmp( arg1, "g_gametype" ) ) { } else if ( !Q_stricmp( arg1, "kick" ) ) { } else if ( !Q_stricmp( arg1, "clientkick" ) ) { } else if ( !Q_stricmp( arg1, "g_doWarmup" ) ) { } else if ( !Q_stricmp( arg1, "timelimit" ) ) { } else if ( !Q_stricmp( arg1, "fraglimit" ) ) { } else { trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" ); trap_SendServerCommand( ent-g_entities, "print \"Vote commands are: map_restart, nextmap, map <mapname>, g_gametype <n>, kick <player>, clientkick <clientnum>, g_doWarmup, timelimit <time>, fraglimit <frags>.\n\"" ); return; } // if there is still a vote to be executed if ( level.voteExecuteTime ) { // don't start a vote when map change or restart is in progress if ( !Q_stricmpn( level.voteString, "map", 3 ) || !Q_stricmpn( level.voteString, "nextmap", 7 ) ) { trap_SendServerCommand( ent-g_entities, "print \"Vote after map change.\n\"" ); return; } level.voteExecuteTime = 0; trap_SendConsoleCommand( EXEC_APPEND, va("%s\n", level.voteString ) ); } // special case for g_gametype, check for bad values if ( !Q_stricmp( arg1, "g_gametype" ) ) { i = atoi( arg2 ); if( i == GT_SINGLE_PLAYER || i < GT_FFA || i >= GT_MAX_GAME_TYPE) { trap_SendServerCommand( ent-g_entities, "print \"Invalid gametype.\n\"" ); return; } Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i ); Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s %s", arg1, gameNames[i] ); } else if ( !Q_stricmp( arg1, "map" ) ) { // special case for map changes, we want to reset the nextmap setting // this allows a player to change maps, but not upset the map rotation char s[MAX_STRING_CHARS]; trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof(s) ); if (*s) { Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s; set nextmap \"%s\"", arg1, arg2, s ); } else { Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 ); } Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString ); } else if ( !Q_stricmp( arg1, "nextmap" ) ) { char s[MAX_STRING_CHARS]; trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof(s) ); if (!*s) { trap_SendServerCommand( ent-g_entities, "print \"nextmap not set.\n\"" ); return; } Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr nextmap"); Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString ); } else if ( !Q_stricmp( arg1, "clientkick" ) || !Q_stricmp( arg1, "kick" ) ) { i = ClientNumberFromString( ent, arg2, !Q_stricmp( arg1, "clientkick" ), !Q_stricmp( arg1, "kick" ) ); if ( i == -1 ) { return; } if ( level.clients[i].pers.localClient ) { trap_SendServerCommand( ent - g_entities, "print \"Cannot kick host player.\n\"" ); return; } Com_sprintf( level.voteString, sizeof( level.voteString ), "clientkick %d", i ); Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "kick %s", level.clients[i].pers.netname ); } else { Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 ); Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString ); } trap_SendServerCommand( -1, va("print \"%s called a vote.\n\"", ent->client->pers.netname ) ); // start the voting, the caller automatically votes yes level.voteTime = level.time; level.voteYes = 1; level.voteNo = 0; for ( i = 0 ; i < level.maxclients ; i++ ) { level.clients[i].ps.eFlags &= ~EF_VOTED; } ent->client->ps.eFlags |= EF_VOTED; trap_SetConfigstring( CS_VOTE_TIME, va("%i", level.voteTime ) ); trap_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString ); trap_SetConfigstring( CS_VOTE_YES, va("%i", level.voteYes ) ); trap_SetConfigstring( CS_VOTE_NO, va("%i", level.voteNo ) ); }