// (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 ); } }
/* ================= ClientInactivityTimer Returns qfalse if the client is dropped ================= */ qboolean ClientInactivityTimer(gclient_t *client) { int i; int counter = 0; // suburb, take viewangles for inactivity drop instead of buttons for (i = 0; i < 3; ++i) { if (client->ps.viewangles[i] == client->pers.oldViewangles[i]) { counter++; } } // OSP - modified if ((g_inactivity.integer == 0 && client->sess.sessionTeam != TEAM_SPECTATOR) || (g_spectatorInactivity.integer == 0 && client->sess.sessionTeam == TEAM_SPECTATOR)) { // give everyone some time, so if the operator sets g_inactivity during // gameplay, everyone isn't kicked client->inactivityTime = level.time + 60 * 1000; client->inactivityWarning = qfalse; } else if (counter != 3) { client->inactivityWarning = qfalse; client->inactivityTime = level.time + 1000 * ((client->sess.sessionTeam != TEAM_SPECTATOR) ? g_inactivity.integer : g_spectatorInactivity.integer); } else if (!client->pers.localClient) { if (level.time > client->inactivityTime && client->inactivityWarning) { client->inactivityWarning = qfalse; client->inactivityTime = level.time + 60 * 1000; // Nico, move inactive player to spec instead of kicking them // trap_DropClient( client - level.clients, "Dropped due to inactivity", 0 ); AP(va("cpm \"%s ^7removed from teams due to inactivity! ^z(%i seconds) \n\"", client->pers.netname, g_inactivity.integer)); SetTeam(g_entities + (client - level.clients), "s", -1, -1, qfalse); return qfalse; } if (!client->inactivityWarning && level.time > client->inactivityTime - 10000) { CPx(client - level.clients, "cp \"^310 seconds until inactivity drop!\n\""); CPx(client - level.clients, "print \"^310 seconds until inactivity drop!\n\""); G_Printf("10s inactivity warning issued to: %s\n", client->pers.netname); client->inactivityWarning = qtrue; client->inactivityTime = level.time + 10000; // Just for safety } } // suburb, update viewangles if (counter != 3) { for (i = 0; i < 3; ++i) { client->pers.oldViewangles[i] = client->ps.viewangles[i]; } } return qtrue; }
/* QUAKED target_startTimer (1 0 0) (-8 -8 -8) (8 8 8) * timer start * * "name" timerun name */ void target_starttimer_use(gentity_t *self, gentity_t *other, gentity_t *activator) { gclient_t *client = activator->client; // Nico, silent GCC (void)other; if (client->sess.timerunActive) { return; } if ((self->spawnflags & 1) && VectorLength(client->ps.velocity) > 600) { // Server or clientside? cvar to toggle whether or not to reset speed in these cases? CPx(activator - g_entities, "cpm \"^1Timerun not started, no prejump allowed!\n\""); return; } if (client->ps.pm_type != PM_NORMAL || client->ps.stats[STAT_HEALTH] <= 0) { CPx(activator - g_entities, "cpm \"^1Timerun not started, invalid playerstate!\n\""); return; } client->sess.currentTimerun = self->timerunName; client->sess.currentTimerunNum = GetTimerunNum(activator->client->sess.currentTimerun); // get the time client->sess.timerunStartTime = client->ps.commandTime; client->sess.startSpeed = (int)sqrt(client->ps.velocity[0] * client->ps.velocity[0] + client->ps.velocity[1] * client->ps.velocity[1]); client->sess.timerunActive = qtrue; // Nico, notify timerun_start event to client and to its spectators notify_timerun_start(activator); // reset checkpoints memset(client->sess.timerunCheckpointTimes, 0, sizeof (client->sess.timerunCheckpointTimes)); client->sess.timerunCheckpointsPassed = 0; // Nico, reset max speed of the run client->sess.maxSpeed = 0; // Nico, reset jump counter (cause prediction error?) client->ps.identifyClientHealth = 0; // Nico, reset saves if physics is VET and strict save/load mod isa DISABLED if (physics.integer == PHYSICS_MODE_VET && g_strictSaveLoad.integer != 1) { int i; for (i = 0; i < MAX_SAVED_POSITIONS; ++i) { client->sess.alliesSaves[i].valid = qfalse; client->sess.axisSaves[i].valid = qfalse; } } }
// Josh: Won't gib if already in limbo, same as shrub void G_CensorPenalize(gentity_t *ent) { if (!ent->client) { return; } // forty - #127 - Burn a potty mouth if (g_censorPenalty.integer & CNSRPNLTY_BURN) { if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR && !(ent->client->ps.pm_flags & PMF_LIMBO) && ent->health >= 0 && level.match_pause == PAUSE_NONE ) { G_BurnMeGood(ent, ent, NULL); AP(va("chat \"^7%s ^7burnt his fingers.\" -1", ent->client->pers.netname)); } } // forty - #127 - censor xp penalty if (g_censorPenalty.integer & CNSRPNLTY_XP) { if (ent->client->sess.sessionTeam != TEAM_SPECTATOR) { CPx(ent - g_entities, va("chat \"^1Warning^7: Watch you mouth!^* You have Lost %d XP.\"", g_censorXP.integer)); G_LoseSkillPoints(ent, BG_ClassSkillForClass(ent->client->sess.playerType), g_censorXP.integer); } } if (g_censorPenalty.integer & CNSRPNLTY_TMPMUTE) { ent->client->sess.auto_unmute_time = (level.time + 1000 * (g_censorMuteTime.integer)); CPx(ent - g_entities, va("print \"^5You've been auto-muted for %d seconds for language.\n\"", g_censorMuteTime.integer)); AP(va("chat \"%s^7 has been auto-muted for %d seconds for language.\" -1", ent->client->pers.netname, g_censorMuteTime.integer)); } if (g_censorPenalty.integer & CNSRPNLTY_KILL) { Force_Suicide(ent); return; } if (g_censorPenalty.integer & CNSRPNLTY_NOGIB) { // KILL, don't GIB ent->flags &= ~FL_GODMODE; ent->client->ps.stats[STAT_HEALTH] = ent->health = 0; ent->client->ps.persistant[PERS_HWEAPON_USE] = 0; // TTimo - if at MG42 player_die(ent, ent, ent, 135, MOD_UNKNOWN); } }
/* ================= ClientInactivityTimer Returns qfalse if the client is dropped ================= */ qboolean ClientInactivityTimer(gclient_t *client) { // OSP - modified if ((g_inactivity.integer == 0 && client->sess.sessionTeam != TEAM_SPECTATOR) || (g_spectatorInactivity.integer == 0 && client->sess.sessionTeam == TEAM_SPECTATOR)) { // give everyone some time, so if the operator sets g_inactivity during // gameplay, everyone isn't kicked client->inactivityTime = level.time + 60 * 1000; client->inactivityWarning = qfalse; } else if (client->pers.cmd.forwardmove || client->pers.cmd.rightmove || client->pers.cmd.upmove || (client->pers.cmd.wbuttons & WBUTTON_ATTACK2) || (client->pers.cmd.buttons & BUTTON_ATTACK) || (client->pers.cmd.wbuttons & WBUTTON_LEANLEFT) || (client->pers.cmd.wbuttons & WBUTTON_LEANRIGHT) || client->ps.pm_type == PM_DEAD) { client->inactivityWarning = qfalse; client->inactivityTime = level.time + 1000 * ((client->sess.sessionTeam != TEAM_SPECTATOR) ? g_inactivity.integer : g_spectatorInactivity.integer); } else if (!client->pers.localClient) { if (level.time > client->inactivityTime && client->inactivityWarning) { client->inactivityWarning = qfalse; client->inactivityTime = level.time + 60 * 1000; // Nico, move inactive player to spec instead of kicking them // trap_DropClient( client - level.clients, "Dropped due to inactivity", 0 ); AP(va("cpm \"%s ^7removed from teams due to inactivity! ^z(%i seconds) \n\"", client->pers.netname, g_inactivity.integer)); SetTeam(g_entities + (client - level.clients), "s", -1, -1, qfalse); return qfalse; } if (!client->inactivityWarning && level.time > client->inactivityTime - 10000) { CPx(client - level.clients, "cp \"^310 seconds until inactivity drop!\n\""); CPx(client - level.clients, "print \"^310 seconds until inactivity drop!\n\""); G_Printf("10s inactivity warning issued to: %s\n", client->pers.netname); client->inactivityWarning = qtrue; client->inactivityTime = level.time + 10000; // Just for safety } } return qtrue; }
// 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(); } }
// (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 ); } }
/* =================== Nolla - noVoteLimit XXX setup - convert to a referee command =================== */ void Svcmd_noVoteLimit() { gclient_t *cl; char name[MAX_TOKEN_CHARS]; trap_Argv(1, name, sizeof(name)); if ((cl = G_GetPlayerByName(name)) == NULL) return; if (cl->sess.noVoteLimit) cl->sess.noVoteLimit = qfalse; else { cl->pers.voteCount = 0; cl->sess.noVoteLimit = qtrue; CPx(cl - level.clients, "cpm \"^7You have not any vote limit now!\n\""); } }
/* QUAKED target_stopTimer (1 0 0) (-8 -8 -8) (8 8 8) * timer stop * * "name" timerun name * "minCheckpoints" minimal passed checkpoints to activate this stoptimer */ void target_stoptimer_use(gentity_t *self, gentity_t *other, gentity_t *activator) { int time; gclient_t *client = activator->client; int timerunNum; // Nico, silent GCC (void)other; if (!client->sess.timerunActive) { return; } // don't stop the time if this isn't a corresponding stoptimer if (Q_stricmp(self->timerunName, client->sess.currentTimerun)) { return; } timerunNum = client->sess.currentTimerunNum; // required number of checkpoints passed? if (client->sess.timerunCheckpointsPassed < self->count) { CPx(activator - g_entities, va("cpm \"^d%s^f:^1 Minimum checkpoints not passed (%d/%d)\n\"", client->sess.currentTimerun, client->sess.timerunCheckpointsPassed, self->count)); notify_timerun_stop(activator, 0); client->sess.timerunActive = qfalse; return; } time = client->sess.timerunLastTime[timerunNum] = client->ps.commandTime - client->sess.timerunStartTime; if (!client->sess.timerunBestTime[timerunNum] || time < client->sess.timerunBestTime[timerunNum]) { // best personal for this session if (client->sess.logged) { client->sess.timerunBestTime[timerunNum] = time; // Nico, update best speed of run client->sess.timerunBestSpeed[timerunNum] = client->sess.maxSpeed; // Nico, set score so that xfire can see it (only if cup mode is DISABLED) if (g_cupMode.integer != 1) { client->ps.persistant[PERS_SCORE] = client->sess.timerunLastTime[timerunNum]; } } // CP are updated here if API is not used or if CP were note loaded if (!g_useAPI.integer || client->sess.timerunCheckpointWereLoaded[timerunNum] == 0) { memcpy(client->sess.timerunBestCheckpointTimes[timerunNum], client->sess.timerunCheckpointTimes, sizeof (client->sess.timerunCheckpointTimes)); } } // Nico, stop speed client->sess.stopSpeed = (int)sqrt(client->ps.velocity[0] * client->ps.velocity[0] + client->ps.velocity[1] * client->ps.velocity[1]); // Nico, send record if needed if (g_useAPI.integer && client->sess.logged) { Cmd_SendRecord_f(activator, client->sess.currentTimerun, client->pers.authToken, time, client->sess.startSpeed, client->sess.stopSpeed, client->sess.maxSpeed, client->ps.identifyClientHealth, // Nico, this is used as a jumps counter client->pers.ip, client->pers.maxFPS, client->pers.clientTimeNudge, client->pers.rate, client->pers.clientMaxPackets, client->pers.snaps, g_strictSaveLoad.integer, g_disableDrowning.integer, g_holdDoorsOpen.integer, g_enableMapEntities.integer); } else { // Nico, API is not used and/or client is not logged, // we cannnot know if his last time his SB/PB or something // else. So we keep his last demo. saveDemo(activator); } // Nico, notify the client and its spectators the timerun has stopped notify_timerun_stop(activator, client->sess.timerunLastTime[timerunNum]); client->sess.timerunActive = qfalse; }
void SoftConstrFunction::Evaluate(const arma::vec &x) { // Vertex coordinates: First convert control points into vertices // verCoords has the form of [x1 x2, x3... y1 y2 y3... z1 z2 z3] // We will compute Jacobian w.r.t vertex variables first, then we compute // Jacobian w.r.t actual variables using composition rules vec vertCoords = this->P * x; vec CPx; CPx.set_size(this->refEdgeLens.n_elem); int nVertVars = this->P.n_rows; // Number of vertex variables = 3 * #vertices int nVerts = nVertVars / 3; // Number of vertices int nEdges = this->refEdgeLens.n_elem; // Number of edges (#constraints) // TODO: Make Jv to be attribute of class to avoid re-allocating each evaluation // Jacobian w.r.t all vertex coordinates. Then this->J = Jv * P since x = P*c mat Jv = zeros(nEdges, nVertVars); // Iterate through all edges to compute function value and derivatives for (int i = 0; i < nEdges; i++) { // An edge has two vertices int vertID1 = edges(0, i); int vertID2 = edges(1, i); // Indices of x,y,z coordinates in the vector vertCoords [x1 x2, x3... y1 y2 y3... z1 z2 z3] int x1Idx = vertID1; int y1Idx = x1Idx + nVerts; int z1Idx = y1Idx + nVerts; int x2Idx = vertID2; int y2Idx = x2Idx + nVerts; int z2Idx = y2Idx + nVerts; // Coordinates of two vertices (x1,y1,z1) & (x2,y2,z2) double x1 = vertCoords(x1Idx); double y1 = vertCoords(y1Idx); double z1 = vertCoords(z1Idx); double x2 = vertCoords(x2Idx); double y2 = vertCoords(y2Idx); double z2 = vertCoords(z2Idx); // Edge length double edgeLen = sqrt( pow(x2-x1, 2) + pow(y2-y1, 2) + pow(z2-z1, 2) ); // Compute function value = "edge length" - "reference edge length" // 有一些存在len大于refLen的边,这不符合实际情况,因此要做constrained optimization CPx(i) = edgeLen - refEdgeLens(i); // if (edgeLen > refEdgeLens(i)) // { // std::cout << "FOUND ONE" << std::endl; // } // Compute derivatives. Recall the derivative: sqrt'(x) = 1/(2*sqrt(x)) Jv(i, x1Idx) = (x1-x2) / edgeLen; Jv(i, y1Idx) = (y1-y2) / edgeLen; Jv(i, z1Idx) = (z1-z2) / edgeLen; Jv(i, x2Idx) = (x2-x1) / edgeLen; Jv(i, y2Idx) = (y2-y1) / edgeLen; Jv(i, z2Idx) = (z2-z1) / edgeLen; } this->F = MPwAP * x; this->C = CPx; // Jacobian w.r.t actual variables using composition chain rule // mat m1 = arma::join_cols(MPwAP, Jv * P); //mat m2 = arma::join_rows(2*trans(MPwAP*x), 2 * trans(CPx)); this->J = MPwAP; this->A = Jv * P; //cout << this->J << endl; vec CPxabs = arma::abs(CPx); #if 0 cout << "Constraint function mean: " << arma::mean(CPxabs) << endl; #endif }
/** * @brief kill command - kills players */ static void Svcmd_Die(void) { int pids[MAX_CLIENTS]; char name[MAX_NAME_LENGTH], err[MAX_STRING_CHARS]; gentity_t *vic; qboolean doAll = qfalse; // FIXME: usage // add reason? // ignore in intermission if (level.intermissiontime) { G_Printf("Die command not allowed during intermission.\n"); return; } if (trap_Argc() < 2) { doAll = qtrue; } trap_Argv(1, name, sizeof(name)); if (!Q_stricmp(name, "-1") || doAll) { int it, count = 0; for (it = 0; it < level.numConnectedClients; it++) { vic = g_entities + level.sortedClients[it]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { continue; } G_Damage(vic, NULL, NULL, NULL, NULL, 140, 0, MOD_UNKNOWN); count++; } if (count > 0) { CPx(-1, va("cp \"^9%d players died.\"", count)); } else { G_Printf("There is no player to die.\n"); } return; } if (ClientNumbersFromString(name, pids) != 1) { G_MatchOnePlayer(pids, err, sizeof(err)); G_Printf("Error - can't execute die command - %s.\n", err); return; } vic = &g_entities[pids[0]]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { G_Printf("Player must be on a team to die.\n"); return; } G_Damage(vic, NULL, NULL, NULL, NULL, 140, 0, MOD_UNKNOWN); CPx(-1, va("cp \"^7%s^7 died.\"", vic->client->pers.netname)); return; }
static void Svcmd_Fling(int flingType) // 0 = fling, 1 = throw, 2 = launch { int pids[MAX_CLIENTS]; char name[MAX_NAME_LENGTH], err[MAX_STRING_CHARS]; char fling[9], pastTense[9]; gentity_t *vic; qboolean doAll = qfalse; switch (flingType) { case 0: Q_strncpyz(fling, "fling", sizeof(fling)); Q_strncpyz(pastTense, "flung", sizeof(pastTense)); break; case 1: Q_strncpyz(fling, "throw", sizeof(fling)); Q_strncpyz(pastTense, "thrown", sizeof(pastTense)); break; case 2: Q_strncpyz(fling, "launch", sizeof(fling)); Q_strncpyz(pastTense, "launched", sizeof(pastTense)); break; default: return; } // ignore in intermission if (level.intermissiontime) { G_Printf("%s command not allowed during intermission.\n", fling); return; } if (trap_Argc() < 2) { doAll = qtrue; } trap_Argv(1, name, sizeof(name)); if (!Q_stricmp(name, "-1") || doAll) { int i, count = 0; for (i = 0; i < level.numConnectedClients; i++) { vic = g_entities + level.sortedClients[i]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { continue; } count += G_FlingClient(vic, flingType); } if (count > 0) { CPx(-1, va("cp \"^9%d players %s.\"", count, pastTense)); } else { G_Printf("No players in team or they are already %s.\n", pastTense); } return; } if (ClientNumbersFromString(name, pids) != 1) { G_MatchOnePlayer(pids, err, sizeof(err)); G_Printf("Error - can't %s - %s.\n", fling, err); return; } vic = &g_entities[pids[0]]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { G_Printf("Player must be on a team to be %s.\n", pastTense); return; } if (G_FlingClient(vic, flingType)) { CPx(-1, va("cp \"^7%s^7 was %s.\"", vic->client->pers.netname, pastTense)); } return; }
/** * @brief pip command - pips players */ static void Svcmd_Pip(void) { int pids[MAX_CLIENTS]; char name[MAX_NAME_LENGTH], err[MAX_STRING_CHARS]; gentity_t *vic; qboolean doAll = qfalse; // FIXME: usage // make all outputs nice - cp with icon? // reason? // ignore in intermission if (level.intermissiontime) { G_Printf("Pip command not allowed during intermission.\n"); return; } if (trap_Argc() < 2) { doAll = qtrue; } trap_Argv(1, name, sizeof(name)); if (!Q_stricmp(name, "-1") || doAll) { int it, count = 0; for (it = 0; it < level.numConnectedClients; it++) { vic = g_entities + level.sortedClients[it]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { continue; } G_Pip(vic); count++; } if (count > 0) { CPx(-1, va("cp \"^9%d players pipped.\"", count)); } else { G_Printf("No players in team or they are already pipped.\n"); } return; } if (ClientNumbersFromString(name, pids) != 1) { G_MatchOnePlayer(pids, err, sizeof(err)); G_Printf("Error - can't pip - %s.\n", err); return; } vic = &g_entities[pids[0]]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { G_Printf("Player must be on a team to be pipped.\n"); return; } G_Pip(vic); CPx(-1, va("cp \"^7%s^7 is pipped.\"", vic->client->pers.netname)); return; }
/** * @brief unfreeze command - unfreezes players */ static void Svcmd_Unfreeze(void) { int pids[MAX_CLIENTS]; char name[MAX_NAME_LENGTH], err[MAX_STRING_CHARS]; gentity_t *vic; qboolean doAll = qfalse; // FIXME: usage // make all outputs nice - cp with icon? // reason? if (trap_Argc() < 2) { doAll = qtrue; } trap_Argv(1, name, sizeof(name)); if (!Q_stricmp(name, "-1") || doAll) { int it, count = 0; for (it = 0; it < level.numConnectedClients; it++) { vic = g_entities + level.sortedClients[it]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { continue; } // only unfreeze & count not frozen players :) if (vic->client->freezed == qfalse) { continue; } vic->client->freezed = qfalse; vic->takedamage = qtrue; count++; } if (count > 0) { CPx(-1, va("cp \"^9%d players are unfrozen.\"", count)); } else { G_Printf("No players in team or they are already unfrozen.\n"); } return; } if (ClientNumbersFromString(name, pids) != 1) { G_MatchOnePlayer(pids, err, sizeof(err)); G_Printf("Error - can't unfreeze - %s.\n", err); return; } vic = &g_entities[pids[0]]; if (!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { G_Printf("Player must be on a team to be unfrozen.\n"); return; } vic->client->freezed = qfalse; vic->takedamage = qtrue; CPx(-1, va("cp \"^7%s^7 is unfrozen.\"", vic->client->pers.netname)); return; }
/* =========== ClientUserInfoChanged Called from ClientConnect when the player first connects and directly by the server system when the player updates a userinfo variable. The game can override any of the settings and call trap_SetUserinfo if desired. ============ */ void ClientUserinfoChanged(int clientNum) { gentity_t *ent; char *s; char oldname[MAX_STRING_CHARS]; char userinfo[MAX_INFO_STRING]; gclient_t *client; char *ip = NULL; // Nico, used to store client ip char *rate = NULL; // Nico, used to store client rate char *snaps = NULL; // Nico, used to store client snaps char *name = NULL; // Nico, used to store client name char oldAuthToken[MAX_QPATH]; // Nico, used to see if auth token was changed ent = g_entities + clientNum; client = ent->client; client->ps.clientNum = clientNum; // Nico, flood protection if (ClientIsFlooding(ent)) { G_LogPrintf("Dropping client %d: flooded userinfo\n", clientNum); trap_DropClient(clientNum, "^1You were kicked because of flooded userinfo", 0); return; } trap_GetUserinfo(clientNum, userinfo, sizeof (userinfo)); // Nico, perform security checks on userinfo string if (!checkUserinfoString(clientNum, userinfo)) { return; } if (g_developer.integer || *g_log.string || g_dedicated.integer) { G_Printf("Userinfo: %s\n", userinfo); } // check for local client ip = Info_ValueForKey(userinfo, "ip"); Q_strncpyz(client->pers.ip, ip, IP_MAX_LENGTH); if (ip && !strcmp(ip, "localhost")) { client->pers.localClient = qtrue; level.fLocalHost = qtrue; client->sess.referee = RL_REFEREE; } // Nico, store rate and snaps rate = Info_ValueForKey(userinfo, "rate"); client->pers.rate = atoi(rate); snaps = Info_ValueForKey(userinfo, "snaps"); client->pers.snaps = atoi(snaps); // Nico, backup old auth token Q_strncpyz(oldAuthToken, client->pers.authToken, sizeof (oldAuthToken)); s = Info_ValueForKey(userinfo, "cg_uinfo"); sscanf(s, "%i %i %i %i %s %i %i %i %i %i %i %i %i %i", &client->pers.clientFlags, &client->pers.clientTimeNudge, &client->pers.clientMaxPackets, // Nico, max FPS &client->pers.maxFPS, // Nico, auth Token (char *)&client->pers.authToken, // Nico, load view angles on load &client->pers.loadViewAngles, // Nico, load weapon on load &client->pers.loadWeapon, // Nico, load position when player dies &client->pers.autoLoad, // Nico, cgaz &client->pers.cgaz, // Nico, hideme &client->pers.hideme, // Nico, client auto demo record setting &client->pers.autoDemo, // Nico, automatically load checkpoints &client->pers.autoLoadCheckpoints, // Nico, persistant specLock (int *)&client->sess.specLocked, // Nico, keep all demos &client->pers.keepAllDemos ); // Nico, check if auth token was changed if (oldAuthToken[0] != '\0' && Q_stricmp(oldAuthToken, client->pers.authToken) && client->sess.logged) { // Nico, auth token was changed => logout player if he was logged in CP("cp \"You are no longer logged in!\n\""); G_LogPrintf("ClientUserinfoChanged: authToken changed for client %d, forcing logout\n", clientNum); ent->client->sess.logged = qfalse; } client->pers.autoActivate = (client->pers.clientFlags & CGF_AUTOACTIVATE) ? PICKUP_TOUCH : PICKUP_ACTIVATE; client->pers.predictItemPickup = ((client->pers.clientFlags & CGF_PREDICTITEMS) != 0); if (client->pers.clientFlags & CGF_AUTORELOAD) { client->pers.bAutoReloadAux = qtrue; client->pmext.bAutoReload = qtrue; } else { client->pers.bAutoReloadAux = qfalse; client->pmext.bAutoReload = qfalse; } // Nico, pmove_fixed client->pers.pmoveFixed = client->pers.clientFlags & CGF_PMOVEFIXED; // Nico, autologin client->pers.autoLogin = client->pers.clientFlags & CGF_AUTOLOGIN; // // Nico, name handling // // Backup old name Q_strncpyz(oldname, client->pers.netname, sizeof (oldname)); // Get new name from userinfo string name = Info_ValueForKey(userinfo, "name"); // Clean the new name ClientCleanName(name, client->pers.netname, sizeof (client->pers.netname)); // Check it's valid if (CheckName(client->pers.netname) != qtrue) { // Invalid name, restore old name Q_strncpyz(client->pers.netname, oldname, sizeof (client->pers.netname)); Info_SetValueForKey(userinfo, "name", oldname); trap_SetUserinfo(clientNum, userinfo); CPx(clientNum, "print \"^1Invalid name, name change refused\n\""); G_LogPrintf("Client %d name change refused\n", clientNum); } else { // Name is valid // Now, check if name was changed or not if (client->pers.connected == CON_CONNECTED && strcmp(oldname, client->pers.netname) != 0) { // Name was changed // Now, check name changes limit if (g_maxNameChanges.integer > -1 && client->pers.nameChanges >= g_maxNameChanges.integer) { // Nico, limit reached, forbid name change Q_strncpyz(client->pers.netname, oldname, sizeof (client->pers.netname)); Info_SetValueForKey(userinfo, "name", oldname); trap_SetUserinfo(clientNum, userinfo); CPx(clientNum, "print \"^1You had too many namechanges\n\""); G_LogPrintf("Client %d name change refused\n", clientNum); return; } client->pers.nameChanges++; trap_SendServerCommand(-1, va("print \"%s" S_COLOR_WHITE " renamed to %s\n\"", oldname, client->pers.netname)); } } // // Nico, end of name handling // client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth; // To communicate it to cgame client->ps.stats[STAT_PLAYER_CLASS] = client->sess.playerType; // Gordon: Not needed any more as it's in clientinfo? // send over a subset of the userinfo keys so other clients can // print scoreboards, display models, and play custom sounds s = va("n\\%s\\t\\%i\\c\\%i\\w\\%i\\lw\\%i\\sw\\%i\\mu\\%i\\ref\\%i\\pm\\%i\\l\\%i\\h\\%i\\cc\\%i", client->pers.netname, client->sess.sessionTeam, client->sess.playerType, client->sess.playerWeapon, client->sess.latchPlayerWeapon, client->sess.latchPlayerWeapon2, client->sess.muted ? 1 : 0, client->sess.referee, client->pers.pmoveFixed ? 1 : 0, // Nico, pmove_fixed client->sess.logged ? 1 : 0, // Nico, login status client->pers.hideme, // Nico, hideme client->sess.countryCode// Nico, country code (GeoIP) ); trap_GetConfigstring(CS_PLAYERS + clientNum, oldname, sizeof (oldname)); trap_SetConfigstring(CS_PLAYERS + clientNum, s); if (!Q_stricmp(oldname, s)) { return; } G_LogPrintf("ClientUserinfoChanged: %i %s\n", clientNum, s); G_DPrintf("ClientUserinfoChanged: %i :: %s\n", clientNum, s); }