/* ================ G_ReadSessionData Called on a reconnect ================ */ void G_ReadSessionData(gclient_t *client) { #ifdef FEATURE_MULTIVIEW int mvc_l, mvc_h; #endif int j; char s[MAX_STRING_CHARS]; qboolean test; trap_Cvar_VariableStringBuffer(va("session%i", (int)(client - level.clients)), s, sizeof(s)); #ifdef FEATURE_MULTIVIEW #ifdef FEATURE_RATING sscanf(s, "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %f %f %f %f %i %i %i %i %i %i %i %i", #else sscanf(s, "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", #endif #else #ifdef FEATURE_RATING sscanf(s, "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %f %f %f %f %i %i %i %i %i %i", #else sscanf(s, "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", #endif #endif (int *)&client->sess.sessionTeam, &client->sess.spectatorTime, (int *)&client->sess.spectatorState, &client->sess.spectatorClient, &client->sess.playerType, &client->sess.playerWeapon, &client->sess.playerWeapon2, &client->sess.latchPlayerType, &client->sess.latchPlayerWeapon, &client->sess.latchPlayerWeapon2, &client->sess.coach_team, &client->sess.referee, &client->sess.spec_invite, &client->sess.spec_team, &client->sess.kills, &client->sess.deaths, &client->sess.gibs, &client->sess.self_kills, &client->sess.team_kills, &client->sess.team_gibs, &client->sess.time_axis, &client->sess.time_allies, &client->sess.time_played, #ifdef FEATURE_RATING &client->sess.mu, &client->sess.sigma, &client->sess.oldmu, &client->sess.oldsigma, #endif #ifdef FEATURE_MULTIVIEW &mvc_l, &mvc_h, #endif // Damage and round count rolled in with weapon stats (below) (int *)&client->sess.muted, &client->sess.ignoreClients[0], &client->sess.ignoreClients[1], &client->pers.enterTime, &client->sess.spawnObjectiveIndex, &client->sess.uci ); #ifdef FEATURE_MULTIVIEW // reinstate MV clients client->pers.mvReferenceList = (mvc_h << 16) | mvc_l; #endif // pull and parse weapon stats *s = 0; trap_Cvar_VariableStringBuffer(va("wstats%i", (int)(client - level.clients)), s, sizeof(s)); if (*s) { G_parseStats(s); if (g_gamestate.integer == GS_PLAYING) { client->sess.rounds++; } } // likely there are more cases in which we don't want this if (g_gametype.integer != GT_SINGLE_PLAYER && g_gametype.integer != GT_COOP && g_gametype.integer != GT_WOLF && g_gametype.integer != GT_WOLF_STOPWATCH && !(g_gametype.integer == GT_WOLF_CAMPAIGN && (g_campaigns[level.currentCampaign].current == 0 || level.newCampaign)) && !(g_gametype.integer == GT_WOLF_LMS && g_currentRound.integer == 0)) { trap_Cvar_VariableStringBuffer(va("sessionstats%i", (int)(client - level.clients)), s, sizeof(s)); // read the clients stats (7) and medals (7) sscanf(s, "%f %f %f %f %f %f %f %i %i %i %i %i %i %i", &client->sess.skillpoints[0], &client->sess.skillpoints[1], &client->sess.skillpoints[2], &client->sess.skillpoints[3], &client->sess.skillpoints[4], &client->sess.skillpoints[5], &client->sess.skillpoints[6], &client->sess.medals[0], &client->sess.medals[1], &client->sess.medals[2], &client->sess.medals[3], &client->sess.medals[4], &client->sess.medals[5], &client->sess.medals[6] ); } G_CalcRank(client); test = (g_altStopwatchMode.integer != 0 || g_currentRound.integer == 1); if (g_gametype.integer == GT_WOLF_STOPWATCH && g_gamestate.integer != GS_PLAYING && test) { G_ClientSwap(client); } if (g_swapteams.integer) { trap_Cvar_Set("g_swapteams", "0"); G_ClientSwap(client); } client->sess.startxptotal = 0; for (j = 0; j < SK_NUM_SKILLS; j++) { client->sess.startskillpoints[j] = client->sess.skillpoints[j]; client->sess.startxptotal += client->sess.skillpoints[j]; } }
/* ================ G_ReadSessionData Called on a reconnect ================ */ void G_ReadSessionData( gclient_t *client ) { int mvc_l, mvc_h; char s[MAX_STRING_CHARS]; qboolean test; trap_Cvar_VariableStringBuffer( va( "session%i", client - level.clients ), s, sizeof(s) ); sscanf( s, "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", (int *)&client->sess.sessionTeam, &client->sess.spectatorTime, (int *)&client->sess.spectatorState, &client->sess.spectatorClient, &client->sess.playerType, // DHM - Nerve &client->sess.playerWeapon, // DHM - Nerve &client->sess.playerWeapon2, &client->sess.latchPlayerType, // DHM - Nerve &client->sess.latchPlayerWeapon, // DHM - Nerve &client->sess.latchPlayerWeapon2, // OSP &client->sess.coach_team, &client->sess.deaths, &client->sess.game_points, &client->sess.kills, &client->sess.referee, &client->sess.spec_invite, &client->sess.spec_team, &client->sess.suicides, &client->sess.team_kills, &mvc_l, &mvc_h // Damage and round count rolled in with weapon stats (below) // OSP , // &client->sess.experience, (int *)&client->sess.muted, &client->sess.ignoreClients[0], &client->sess.ignoreClients[1], &client->pers.enterTime, &client->sess.spawnObjectiveIndex ); // OSP -- reinstate MV clients client->pers.mvReferenceList = (mvc_h << 16) | mvc_l; // OSP // OSP -- pull and parse weapon stats *s = 0; trap_Cvar_VariableStringBuffer(va("wstats%i", client - level.clients), s, sizeof(s)); if(*s) { G_parseStats(s); if(g_gamestate.integer == GS_PLAYING) client->sess.rounds++; } // OSP // Arnout: likely there are more cases in which we don't want this if( g_gametype.integer != GT_SINGLE_PLAYER && g_gametype.integer != GT_COOP && g_gametype.integer != GT_WOLF && g_gametype.integer != GT_WOLF_STOPWATCH && !(g_gametype.integer == GT_WOLF_CAMPAIGN && ( g_campaigns[level.currentCampaign].current == 0 || level.newCampaign ) ) && !(g_gametype.integer == GT_WOLF_LMS && g_currentRound.integer == 0 ) ) { trap_Cvar_VariableStringBuffer( va( "sessionstats%i", client - level.clients ), s, sizeof(s) ); // Arnout: read the clients stats (7) and medals (7) sscanf( s, "%f %f %f %f %f %f %f %i %i %i %i %i %i %i", &client->sess.skillpoints[0], &client->sess.skillpoints[1], &client->sess.skillpoints[2], &client->sess.skillpoints[3], &client->sess.skillpoints[4], &client->sess.skillpoints[5], &client->sess.skillpoints[6], &client->sess.medals[0], &client->sess.medals[1], &client->sess.medals[2], &client->sess.medals[3], &client->sess.medals[4], &client->sess.medals[5], &client->sess.medals[6] ); } G_CalcRank( client ); test = (g_altStopwatchMode.integer != 0 || g_currentRound.integer == 1); if(g_gametype.integer == GT_WOLF_STOPWATCH && g_gamestate.integer != GS_PLAYING && test) { G_ClientSwap(client); } if ( g_swapteams.integer ) { trap_Cvar_Set( "g_swapteams", "0" ); G_ClientSwap(client); } { int j; client->sess.startxptotal = 0; for( j = 0; j < SK_NUM_SKILLS; j++ ) { client->sess.startskillpoints[j] = client->sess.skillpoints[j]; client->sess.startxptotal += client->sess.skillpoints[j]; } } }
qboolean G_xpsave_load(gentity_t *ent) { int i, j; qboolean found = qfalse, XPSMuted = qfalse; int clientNum; g_xpsave_t *x = g_xpsaves[0]; time_t t; char agestr[MAX_STRING_CHARS]; //char desc[64]; // josh: Increased this // josh: TODO: tjw? What is this desc thing for? char desc[115]; int age; int eff_XPSaveMaxAge_xp = G_getXPSaveMaxAge_xp(); int eff_XPSaveMaxAge = G_getXPSaveMaxAge(); float startxptotal = 0.0f; if(!ent || !ent->client) return qfalse; if(!(g_XPSave.integer & XPSF_ENABLE)) return qfalse; if(!time(&t)) return qfalse; desc[0] = '\0'; clientNum = ent - g_entities; for(i=0; g_xpsaves[i]; i++) { if(!Q_stricmp(g_xpsaves[i]->guid, ent->client->sess.guid)) { found = qtrue; x = g_xpsaves[i]; break; } } if(!found) return qfalse; age = t - x->time; if(age > eff_XPSaveMaxAge) { return qfalse; } if(age <= eff_XPSaveMaxAge_xp) { for(i=0; i<SK_NUM_SKILLS; i++) { ent->client->sess.skillpoints[i] = x->skill[i]; // pheno: fix for session startxptotal value startxptotal += x->skill[i]; } ent->client->sess.startxptotal = startxptotal; ent->client->ps.stats[STAT_XP] = (int)ent->client->sess.startxptotal; Q_strcat(desc, sizeof(desc), "XP/"); if((g_XPDecay.integer & XPDF_ENABLE) && !(g_XPDecay.integer & XPDF_NO_DISCONNECT_DECAY)) { G_XPDecay(ent, age, qtrue); } } ent->client->sess.overall_killrating = x->kill_rating; ent->client->sess.overall_killvariance = x->kill_variance; //ent->client->sess.playerrating = x->playerrating; ent->client->sess.rating = x->rating; ent->client->sess.rating_variance = x->rating_variance; for(i=0; i<SK_NUM_SKILLS; i++) { for(j=0; j<NUM_SKILL_LEVELS; j++) { ent->client->sess.pr_skill_updates[i][j] = x->pr_skill_updates[i][j]; ent->client->sess.pr_skill[i][j] = x->pr_skill[i][j]; } } Q_strcat(desc, sizeof(desc), "ratings/"); if(x->mutetime != 0) { if(x->mutetime < 0){ ent->client->sess.auto_unmute_time = -1; XPSMuted = qtrue; }else if(x->mutetime > t){ ent->client->sess.auto_unmute_time = (level.time + 1000*(x->mutetime - t)); XPSMuted = qtrue;; } if(XPSMuted == qtrue){ CP("print \"^5You've been muted by XPSave\n\"" ); Q_strcat(desc, sizeof(desc), "mute/"); } } ent->client->sess.hits = x->hits; ent->client->sess.team_hits = x->team_hits; G_CalcRank(ent->client); BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, level.time, qtrue); // tjw: trim last / from desc if(strlen(desc)) desc[strlen(desc)-1] = '\0'; G_shrubbot_duration(age, agestr, sizeof(agestr)); CP(va( "print \"^3server: loaded stored ^7%s^3 state from %s ago\n\"", desc, agestr)); // josh: check and update if disconnect found // cs: not for bots since it is pointless for them, plus we never want SetTeam failing for them if (!(ent->r.svFlags & SVF_BOT)) { Reconnect(x,ent); } return qtrue; }
/** * @brief G_ResetXP * @param[in,out] ent */ void G_ResetXP(gentity_t *ent) { int i = 0; int ammo[MAX_WEAPONS], ammoclip[MAX_WEAPONS]; int oldWeapon; //, newWeapon; if (!ent || !ent->client) { return; } #ifdef FEATURE_RATING if (!g_skillRating.integer) #endif { ent->client->sess.rank = 0; } for (i = 0; i < SK_NUM_SKILLS; i++) { ent->client->sess.skillpoints[i] = 0.0f; ent->client->sess.skill[i] = 0; } G_CalcRank(ent->client); ent->client->ps.stats[STAT_XP] = 0; ent->client->ps.persistant[PERS_SCORE] = 0; // zero out all weapons and grab the default weapons for a player of this XP level. // backup.. Com_Memcpy(ammo, ent->client->ps.ammo, sizeof(ammo)); Com_Memcpy(ammoclip, ent->client->ps.ammoclip, sizeof(ammoclip)); oldWeapon = ent->client->ps.weapon; // Check weapon validity, maybe dump some weapons for this (now) unskilled player.. // It also sets the (possibly new) amounts of ammo for weapons. SetWolfSpawnWeapons(ent->client); // restore.. //newWeapon = ent->client->ps.weapon; for (i = WP_NONE; i < WP_NUM_WEAPONS; ++i) //i<MAX_WEAPONS { // only restore ammo for valid weapons.. // ..they might have lost some weapons because of skill changes. // Also restore to the old amount of ammo, because.. // ..SetWolfSpawnWeapons sets amount of ammo for a fresh spawning player, // which is usually more than the player currently has left. if (COM_BitCheck(ent->client->ps.weapons, i)) { if (ammo[i] < ent->client->ps.ammo[i]) { ent->client->ps.ammo[i] = ammo[i]; } if (ammoclip[i] < ent->client->ps.ammoclip[i]) { ent->client->ps.ammoclip[i] = ammoclip[i]; } } else { ent->client->ps.ammo[i] = 0; ent->client->ps.ammoclip[i] = 0; } } // check if the old weapon is still valid. // If so, restore to the last used weapon.. if (COM_BitCheck(ent->client->ps.weapons, oldWeapon)) { ent->client->ps.weapon = oldWeapon; } ClientUserinfoChanged(ent - g_entities); }
/* ================ G_ReadSessionData Called on a reconnect ================ */ void G_ReadSessionData( gclient_t *client ) { int mvc_l, mvc_h, need_greeting; char s[MAX_STRING_CHARS]; qboolean test; qboolean load = qfalse; trap_Cvar_VariableStringBuffer( va( "session%i", client - level.clients ), s, sizeof(s) ); sscanf( s, "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %f %f %f %f %i %i %i %i %i %i %i %i %i %i %i %i %i %s %s %u %d %i %i", //mcwf GeoIP (int *)&client->sess.sessionTeam, &client->sess.spectatorTime, (int *)&client->sess.spectatorState, &client->sess.spectatorClient, &client->sess.playerType, // DHM - Nerve &client->sess.playerWeapon, // DHM - Nerve &client->sess.playerWeapon2, &client->sess.latchPlayerType, // DHM - Nerve &client->sess.latchPlayerWeapon, // DHM - Nerve &client->sess.latchPlayerWeapon2, // OSP &client->sess.coach_team, &client->sess.deaths, &client->sess.game_points, &client->sess.kills, &client->sess.overall_killrating, &client->sess.overall_killvariance, &client->sess.rating, &client->sess.rating_variance, &client->sess.referee, &client->sess.spec_invite, &client->sess.spec_team, &client->sess.suicides, &client->sess.team_kills, &mvc_l, &mvc_h // Damage and round count rolled in with weapon stats (below) // OSP , // &client->sess.experience, (int *)&client->sess.auto_unmute_time, &client->sess.ignoreClients[0], &client->sess.ignoreClients[1], &client->pers.enterTime, &client->sess.spawnObjectiveIndex, &client->sess.ATB_count, // Dens: Needed to prevent spoofing client->sess.guid, client->sess.ip, &client->sess.uci, //mcwf GeoIP &need_greeting, // quad: shoutcaster and ettv &client->sess.shoutcaster, &client->sess.ettv ); client->sess.need_greeting = (need_greeting == 1) ? qtrue : qfalse; // OSP -- reinstate MV clients client->pers.mvReferenceList = (mvc_h << 16) | mvc_l; // OSP // tjw: don't bother storing weapon stats between rounds /* // OSP -- pull and parse weapon stats *s = 0; trap_Cvar_VariableStringBuffer(va("wstats%i", client - level.clients), s, sizeof(s)); if(*s) { G_parseStats(s); if(g_gamestate.integer == GS_PLAYING) client->sess.rounds++; } // OSP */ // Arnout: likely there are more cases in which we don't want this // tjw: sorry this hurts my brain /* if( g_gametype.integer != GT_SINGLE_PLAYER && g_gametype.integer != GT_COOP && g_gametype.integer != GT_WOLF && g_gametype.integer != GT_WOLF_STOPWATCH && !(g_gametype.integer == GT_WOLF_CAMPAIGN && ( g_campaigns[level.currentCampaign].current == 0 || level.newCampaign ) ) && !(g_gametype.integer == GT_WOLF_LMS && g_currentRound.integer == 0 ) ) { */ load = qfalse; if(g_gametype.integer == GT_WOLF_CAMPAIGN) { // tjw: only load scores back in if this map isn't starting // a new campaign load = !(g_campaigns[level.currentCampaign].current == 0 || level.newCampaign); } if(g_gametype.integer == GT_WOLF_LMS) { // tjw: only load scores back if this isn't the first round load = (g_currentRound.integer != 0); } switch(g_gametype.integer) { case GT_WOLF_CAMPAIGN: case GT_WOLF_LMS: case GT_WOLF_STOPWATCH: case GT_WOLF: case GT_WOLF_MAPVOTE: if(g_XPSave.integer & XPSF_NR_EVER) load = qtrue; if((g_XPSave.integer & XPSF_NR_MAPRESET) && g_reset.integer) load = qtrue; } if(load) { trap_Cvar_VariableStringBuffer( va( "sessionstats%i", client - level.clients ), s, sizeof(s) ); // Arnout: read the clients stats (7) and medals (7) sscanf( s, "%f %f %f %f %f %f %f %i %i %i %i %i %i %i", &client->sess.skillpoints[0], &client->sess.skillpoints[1], &client->sess.skillpoints[2], &client->sess.skillpoints[3], &client->sess.skillpoints[4], &client->sess.skillpoints[5], &client->sess.skillpoints[6], &client->sess.medals[0], &client->sess.medals[1], &client->sess.medals[2], &client->sess.medals[3], &client->sess.medals[4], &client->sess.medals[5], &client->sess.medals[6] ); } G_CalcRank( client ); test = (g_altStopwatchMode.integer != 0 || g_currentRound.integer == 1); if(g_gametype.integer == GT_WOLF_STOPWATCH && g_gamestate.integer != GS_PLAYING && test) { G_ClientSwap(client); } if ( g_swapteams.integer ) { trap_Cvar_Set( "g_swapteams", "0" ); G_ClientSwap(client); } { int j; client->sess.startxptotal = 0; for( j = 0; j < SK_NUM_SKILLS; j++ ) { client->sess.startskillpoints[j] = client->sess.skillpoints[j]; client->sess.startxptotal += client->sess.skillpoints[j]; } } }