/** * @brief Checks whether the connection is valid or invalid and set some * user info keys. * @param[in,out] player The player that is trying to connect to the game * @param[in,out] userinfo The userinfo data that is checked and changed * @param[in] userinfoSize The size of the userinfo buffer * @sa G_ClientDisconnect * @sa CL_ConnectionlessPacket * @todo Check if the teamnum preference has already reached maxsoldiers * and reject connection if so * @return @c false if the connection is refused, @c true otherwise */ bool G_ClientConnect (player_t * player, char *userinfo, size_t userinfoSize) { const char *value; value = Info_ValueForKey(userinfo, "ip"); Com_Printf("connection attempt from %s\n", value); /* check to see if they are on the banned IP list */ if (SV_FilterPacket(value)) { Info_SetValueForKey(userinfo, userinfoSize, "rejmsg", REJ_BANNED); return false; } if (!G_PlayerToPM(player)) { Info_SetValueForKey(userinfo, userinfoSize, "rejmsg", "Server is full"); return false; } value = Info_ValueForKey(userinfo, "password"); if (password->string[0] != '\0' && !Q_streq(password->string, "none") && !Q_streq(password->string, value)) { Info_SetValueForKey(userinfo, userinfoSize, "rejmsg", REJ_PASSWORD_REQUIRED_OR_INCORRECT); return false; } /* fix for fast reconnects after a disconnect */ if (player->inuse) { gi.BroadcastPrintf(PRINT_CONSOLE, "%s already in use.\n", player->pers.netname); G_ClientDisconnect(player); } /* reset persistent data */ OBJZERO(player->pers); G_ClientUserinfoChanged(player, userinfo); gi.BroadcastPrintf(PRINT_CONSOLE, "%s is connecting...\n", player->pers.netname); return true; }
qboolean G_RemoveBot ( gentity_t *ent ) { if( gi.Argc() <= 1 ) { gi.Printf( "Usage: removebot [numbots]\n" ); return qfalse; } for( int n = game.maxclients - 1; n >= maxclients->integer; n-- ) { gentity_t *e = &g_entities[ n ]; if( e->inuse && e->client ) { G_ClientDisconnect( e ); } } return qtrue; }
/** * @brief Sets the teamnum var for this match * @param[in] player Pointer to connected player * @todo Check whether there are enough free spawnpoints in all cases */ static void G_GetTeam (player_t * player) { player_t *p; int playersInGame = 0; /* player has already a team */ if (player->pers.team > 0) { Com_DPrintf(DEBUG_GAME, "Player %s is already on team %i\n", player->pers.netname, player->pers.team); return; } /* number of currently connected players (no ai players) */ p = NULL; while ((p = G_PlayerGetNextActiveHuman(p))) playersInGame++; /* randomly assign a teamnumber in deathmatch games */ if (playersInGame <= 1 && sv_maxclients->integer > 1 && !sv_teamplay->integer) { int spawnCheck[MAX_TEAMS]; int spawnSpots = 0; int randomSpot; int i; /* skip civilian teams */ for (i = TEAM_PHALANX; i < MAX_TEAMS; i++) { spawnCheck[i] = 0; /* check whether there are spawnpoints for this team */ if (level.num_spawnpoints[i]) spawnCheck[spawnSpots++] = i; } /* we need at least 2 different team spawnpoints for multiplayer in a death match game */ if (spawnSpots < 2) gi.Error("G_GetTeam: Not enough spawn spots in map!"); /* assign random valid team number */ i = spawnSpots; randomSpot = rand() % spawnSpots; for (;;) { const int team = spawnCheck[randomSpot]; if (i == 0) gi.Error("G_GetTeam: Could not assign a team!"); if (G_SetTeamForPlayer(player, team)) { gi.DPrintf("%s has been randomly assigned to team %i\n", player->pers.netname, G_ClientGetTeamNum(player)); break; } i--; randomSpot = (randomSpot + 1) % spawnSpots; } return; } /* find a team */ if (sv_maxclients->integer == 1) G_SetTeamForPlayer(player, TEAM_PHALANX); else if (sv_teamplay->integer) { /* set the team specified in the userinfo */ const int i = G_ClientGetTeamNumPref(player); gi.DPrintf("Get a team for teamplay for %s\n", player->pers.netname); /* civilians are at team zero */ if (i > TEAM_CIVILIAN && sv_maxteams->integer >= i) { G_SetTeamForPlayer(player, i); gi.BroadcastPrintf(PRINT_CONSOLE, "serverconsole: %s has chosen team %i\n", player->pers.netname, i); } else { gi.DPrintf("Team %i is not valid - choose a team between 1 and %i\n", i, sv_maxteams->integer); G_SetTeamForPlayer(player, TEAM_DEFAULT); } } else { int i; /* search team */ gi.DPrintf("Getting a multiplayer team for %s\n", player->pers.netname); for (i = TEAM_CIVILIAN + 1; i < MAX_TEAMS; i++) { if (level.num_spawnpoints[i]) { bool teamAvailable = true; p = NULL; /* check if team is in use (only human controlled players) */ while ((p = G_PlayerGetNextActiveAI(p))) { if (p->pers.team == i) { Com_DPrintf(DEBUG_GAME, "Team %i is already in use\n", i); /* team already in use */ teamAvailable = false; break; } } if (teamAvailable) break; } } /* set the team */ if (i < MAX_TEAMS) { /* remove ai player */ p = NULL; while ((p = G_PlayerGetNextActiveHuman(p))) { if (p->pers.team == i) { gi.BroadcastPrintf(PRINT_CONSOLE, "Removing ai player..."); p->inuse = false; break; } } Com_DPrintf(DEBUG_GAME, "Assigning %s to team %i\n", player->pers.netname, i); G_SetTeamForPlayer(player, i); } else { gi.DPrintf("No free team - disconnecting '%s'\n", player->pers.netname); G_ClientDisconnect(player); } } }