/* =========== ClientConnect Called when a player begins connecting to the server. The game can refuse entrance to a client by returning false. If the client is allowed, the connection process will continue and eventually get to ClientBegin() Changing levels will NOT cause this to be called again, but loadgames will. ============ */ qboolean ClientConnect (edict_t *ent, char *userinfo) { char *value; // check to see if they are on the banned IP list value = Info_ValueForKey (userinfo, "ip"); // check for a password value = Info_ValueForKey (userinfo, "password"); if (strcmp(password->string, value) != 0) return false; // they can connect ent->client = game.clients + (ent - g_edicts - 1); // if there is already a body waiting for us (a loadgame), just // take it, otherwise spawn one from scratch if (ent->inuse == false) { // clear the respawning variables InitClientResp (ent->client); if (!game.autosaved || !ent->client->pers.weapon) InitClientPersistant (ent->client); } ClientUserinfoChanged (ent, userinfo); if (game.maxclients > 1) gi.dprintf ("%s connected\n", ent->client->pers.netname); ent->client->pers.connected = true; return true; }
/* ===================== ClientBeginDeathmatch A client has just connected to the server in deathmatch mode, so clear everything out before starting them. ===================== */ void ClientBeginDeathmatch (edict_t *ent) { G_InitEdict (ent); InitClientResp (ent->client); // locate ent at a spawn point PutClientInServer (ent); if (level.intermissiontime) { MoveClientToIntermission (ent); } else { // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (ent->s.origin, MULTICAST_PVS); } gi.bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); // make sure all view stuff is valid ClientEndServerFrame (ent); }
/* =========== ClientBegin called when a client has finished connecting, and is ready to be placed into the game. This will happen every level load. ============ */ void ClientBegin (edict_t *ent) { int i; ent->client = game.clients + (ent - g_edicts - 1); if (deathmatch->value) { ClientBeginDeathmatch (ent); return; } // if there is already a body waiting for us (a loadgame), just // take it, otherwise spawn one from scratch if (ent->inuse == true) { // the client has cleared the client side viewangles upon // connecting to the server, which is different than the // state when the game is saved, so we need to compensate // with deltaangles for (i=0 ; i<3 ; i++) ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(ent->client->ps.viewangles[i]); } else { // a spawn point will completely reinitialize the entity // except for the persistant data that was initialized at // ClientConnect() time G_InitEdict (ent); ent->classname = "player"; InitClientResp (ent->client); PutClientInServer (ent); } if (level.intermissiontime) { MoveClientToIntermission (ent); } else { // send effect if in a multiplayer game if (game.maxclients > 1) { gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (ent->s.origin, MULTICAST_PVS); #ifdef WITH_ACEBOT safe_bprintf #else gi.bprintf #endif (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); } } // make sure all view stuff is valid ClientEndServerFrame (ent); }
/////////////////////////////////////////////////////////////////////// // Spawn the bot /////////////////////////////////////////////////////////////////////// void BOT_SpawnBot (char *team, char *name, char *skin, char *userinfo) { edict_t *bot; if( !nav.loaded ) { Com_Printf("Can't spawn bots without a valid navigation file\n"); return; } bot = BOT_FindFreeClient (); if (!bot) { safe_bprintf (PRINT_MEDIUM, "Server is full, increase Maxclients.\n"); return; } //init the bot bot->inuse = true; bot->yaw_speed = 100; // To allow bots to respawn if(userinfo == NULL) BOT_SetName(bot, name, skin, team); else ClientConnect (bot, userinfo); G_InitEdict (bot); G_SpawnAI(bot); //jabot092(2) bot->ai->is_bot = true; InitClientResp (bot->client); PutClientInServer(bot); BOT_StartAsSpectator (bot); //skill bot->ai->pers.skillLevel = (int)(random()*MAX_BOT_SKILL); if (bot->ai->pers.skillLevel > MAX_BOT_SKILL) //fix if off-limits bot->ai->pers.skillLevel = MAX_BOT_SKILL; else if (bot->ai->pers.skillLevel < 0) bot->ai->pers.skillLevel = 0; BOT_DMclass_InitPersistant(bot); AI_ResetWeights(bot); AI_ResetNavigation(bot); bot->think = BOT_JoinGame; bot->nextthink = level.time + (int)(random()*6.0); if( ctf->value && team != NULL ) { if( !Q_stricmp( team, "blue" ) ) bot->think = BOT_JoinBlue; else if( !Q_stricmp( team, "red" ) ) bot->think = BOT_JoinRed; } AI_EnemyAdded (bot); // let the ai know we added another }
/* ===================== ClientBeginDeathmatch A client has just connected to the server in deathmatch mode, so clear everything out before starting them. ===================== */ void ClientBeginDeathmatch (edict_t *ent) { #ifdef WITH_ACEBOT // ACEBOT_ADD static char current_map[55]; // ACEBOT_END #endif G_InitEdict (ent); #ifdef WITH_ACEBOT // ACEBOT_ADD ACEIT_PlayerAdded(ent); // ACEBOT_END #endif InitClientResp (ent->client); // locate ent at a spawn point PutClientInServer (ent); // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (ent->s.origin, MULTICAST_PVS); #ifdef WITH_ACEBOT safe_bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); safe_centerprintf(ent,"\nQ2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2\n\nZaero Bots\n\n\n'sv addbot' to add a new bot.\n\n'sv removebot <name>' to remove bot.\n\n\nhttp://qudos.quakedev.com\n\n\nQ2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2\n\n"); // If the map changes on us, init and reload the nodes if(strcmp(level.mapname,current_map)) { ACEND_InitNodes(); ACEND_LoadNodes(); if (botauto_respawn->value) { ACESP_LoadBots(); } strcpy(current_map,level.mapname); } safe_bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); // ACEBOT_END #else gi.bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); #endif // make sure all view stuff is valid ClientEndServerFrame (ent); }
void ClientBeginDeathmatch (edict_t *ent) { // STEVE added these 3 local variables FILE *motd_file; char motd[500]; char line[80]; G_InitEdict (ent); InitClientResp (ent->client); // locate ent at a spawn point PutClientInServer (ent); // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (ent->s.origin, MULTICAST_PVS); gi.bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); // STEVE changed this bit : read the motd from a file if (motd_file = fopen("motd.txt", "r")) { // we successfully opened the file "motd.txt" if ( fgets(motd, 500, motd_file) ) { // we successfully read a line from "motd.txt" into motd // ... read the remaining lines now while ( fgets(line, 80, motd_file) ) { // add each new line to motd, to create a BIG message string. // we are using strcat: STRing conCATenation function here. strcat(motd, line); } // print our message. gi.centerprintf (ent, motd); } // be good now ! ... close the file fclose(motd_file); } // make sure all view stuff is valid ClientEndServerFrame (ent); }
/////////////////////////////////////////////////////////////////////// // Spawn the bot /////////////////////////////////////////////////////////////////////// void ACESP_SpawnBot (char *team, char *name, char *skin, char *userinfo) { edict_t *bot; bot = ACESP_FindFreeClient (); if (!bot) { safe_bprintf (PRINT_MEDIUM, "Server is full, increase Maxclients.\n"); return; } bot->yaw_speed = 100; // yaw speed bot->inuse = true; bot->is_bot = true; // To allow bots to respawn if(userinfo == NULL) ACESP_SetName(bot, name, skin, team); else ClientConnect (bot, userinfo); G_InitEdict (bot); InitClientResp (bot->client); // locate ent at a spawn point /*if(ctf->value) { if (team != NULL && strcmp(team,"red")==0) ACESP_PutClientInServer (bot,false, CTF_TEAM1); else ACESP_PutClientInServer (bot,false, CTF_TEAM2); } else*/ ACESP_PutClientInServer (bot,false,0); // make sure all view stuff is valid ClientEndServerFrame (bot); ACEIT_PlayerAdded (bot); // let the world know we added another ACEAI_PickLongRangeGoal(bot); // pick a new goal }
/////////////////////////////////////////////////////////////////////// // Spawn the bot /////////////////////////////////////////////////////////////////////// void ACESP_SpawnBot(char *team, char *name, char *skin, char *userinfo) { edict_t *bot = ACESP_FindFreeClient(); if (!bot) { safe_bprintf(PRINT_MEDIUM, "Server is full, increase Maxclients.\n"); return; } bot->yaw_speed = 100; // yaw speed bot->inuse = true; bot->is_bot = true; // To allow bots to respawn if (userinfo == NULL) ACESP_SetName(bot, name, skin, team); else ClientConnect (bot, userinfo); G_InitEdict (bot); InitClientResp (bot->client); // locate ent at a spawn point if (ctf->value) { // Knightmare- rewrote this int team1count = 0, team2count = 0, team3count = 0; int jointeam; const float r = random(); for (int i = 1; i <= maxclients->value; i++) { edict_t *player = &g_edicts[i]; if (!player->inuse || !player->client || player == bot) continue; switch (player->client->resp.ctf_team) { case CTF_TEAM1: team1count++; break; case CTF_TEAM2: team2count++; break; case CTF_TEAM3: team3count++; break; } } if (ttctf->value) { if (team != NULL && strcmp(team,"red")==0) jointeam = CTF_TEAM1; else if (team != NULL && strcmp(team,"blue")==0) jointeam = CTF_TEAM2; else if (team != NULL && strcmp(team,"green")==0) jointeam = CTF_TEAM3; // join either of the outnumbered teams else if (team1count == team2count && team1count < team3count) jointeam = (r < 0.5) ? CTF_TEAM1 : CTF_TEAM2; else if (team1count == team3count && team1count < team2count) jointeam = (r < 0.5) ? CTF_TEAM1 : CTF_TEAM3; else if (team2count == team3count && team2count < team1count) jointeam = (r < 0.5) ? CTF_TEAM2 : CTF_TEAM3; // join outnumbered team else if (team1count < team2count && team1count < team3count) jointeam = CTF_TEAM1; else if (team2count < team1count && team2count < team3count) jointeam = CTF_TEAM2; else if (team3count < team1count && team3count < team2count) jointeam = CTF_TEAM3; // pick random team else if (r < 0.33) jointeam = CTF_TEAM1; else if (r < 0.66) jointeam = CTF_TEAM2; else jointeam = CTF_TEAM3; } else { if (team != NULL && strcmp(team,"red")==0) jointeam = CTF_TEAM1; else if (team != NULL && strcmp(team,"blue")==0) jointeam = CTF_TEAM2; // join outnumbered team else if (team1count < team2count) jointeam = CTF_TEAM1; else if (team2count < team1count) jointeam = CTF_TEAM2; // pick random team else if (r < 0.5) jointeam = CTF_TEAM1; else jointeam = CTF_TEAM2; } ACESP_PutClientInServer (bot,false, jointeam); } else ACESP_PutClientInServer (bot,false,0); // make sure all view stuff is valid ClientEndServerFrame(bot); ACEIT_PlayerAdded(bot); // let the world know we added another ACEAI_PickLongRangeGoal(bot); // pick a new goal }
/* =========== ClientConnect Called when a player begins connecting to the server. The game can refuse entrance to a client by returning false. If the client is allowed, the connection process will continue and eventually get to ClientBegin() Changing levels will NOT cause this to be called again, but loadgames will. ============ */ qboolean ClientConnect (edict_t *ent, char *userinfo) { char *value; // check to see if they are on the banned IP list value = Info_ValueForKey (userinfo, "ip"); if (SV_FilterPacket(value)) { Info_SetValueForKey(userinfo, "rejmsg", "Banned."); return false; } // check for a spectator value = Info_ValueForKey (userinfo, "spectator"); if (deathmatch->value && *value && strcmp(value, "0")) { int i, numspec; if (*spectator_password->string && strcmp(spectator_password->string, "none") && strcmp(spectator_password->string, value)) { Info_SetValueForKey(userinfo, "rejmsg", "Spectator password required or incorrect."); return false; } // count spectators for (i = numspec = 0; i < maxclients->value; i++) if (g_edicts[i+1].inuse && g_edicts[i+1].client->pers.spectator) numspec++; if (numspec >= maxspectators->value) { Info_SetValueForKey(userinfo, "rejmsg", "Server spectator limit is full."); return false; } } else { // check for a password value = Info_ValueForKey (userinfo, "password"); if (*password->string && strcmp(password->string, "none") && strcmp(password->string, value)) { Info_SetValueForKey(userinfo, "rejmsg", "Password required or incorrect."); return false; } } // they can connect ent->client = game.clients + (ent - g_edicts - 1); // if there is already a body waiting for us (a loadgame), just // take it, otherwise spawn one from scratch if (ent->inuse == false) { // clear the respawning variables InitClientResp (ent->client); if (!game.autosaved || !ent->client->pers.weapon) InitClientPersistant (ent->client); } ClientUserinfoChanged (ent, userinfo); if (game.maxclients > 1) gi.dprintf ("%s connected\n", ent->client->pers.netname); ent->svflags = 0; // make sure we start with known default ent->client->pers.connected = true; return true; }