bool displayGameOver(bool bDidit) { if (bDidit) { setPlayerHasWon(true); multiplayerWinSequence(true); if (bMultiPlayer) { updateMultiStatsWins(); } } else { setPlayerHasLost(true); if (bMultiPlayer) { updateMultiStatsLoses(); } } if (bMultiPlayer) { PLAYERSTATS st = getMultiStats(selectedPlayer); saveMultiStats(getPlayerName(selectedPlayer), getPlayerName(selectedPlayer), &st); } //clear out any mission widgets - timers etc that may be on the screen clearMissionWidgets(); intAddMissionResult(bDidit, true); return true; }
// //////////////////////////////////////////////////////////////////////////// // Load Player Stats bool loadMultiStats(char *sPlayerName, PLAYERSTATS *st) { char fileName[255]; UDWORD size; char *pFileData; memset(st, 0, sizeof(PLAYERSTATS)); // clear in case we don't get to load // Prevent an empty player name (where the first byte is a 0x0 terminating char already) if (!*sPlayerName) { strcpy(sPlayerName, _("Player")); } snprintf(fileName, sizeof(fileName), "%s%s.sta", MultiPlayersPath, sPlayerName); debug(LOG_WZ, "loadMultiStats: %s", fileName); // check player already exists if ( !PHYSFS_exists( fileName ) ) { PLAYERSTATS blankstats; memset(&blankstats, 0, sizeof(PLAYERSTATS)); saveMultiStats(sPlayerName,sPlayerName,&blankstats); // didnt exist so create. } else { int num = 0; loadFile(fileName,&pFileData,&size); if (strncmp(pFileData, "WZ.STA.v3", 9) != 0) { return false; // wrong version or not a stats file } num = sscanf(pFileData, "WZ.STA.v3\n%u %u %u %u %u", &st->wins, &st->losses, &st->totalKills, &st->totalScore, &st->played); if (num < 5) { st->played = 0; // must be old, buggy format still } free(pFileData); } // reset recent scores st->recentKills = 0; st->recentScore = 0; // clear any skirmish stats. for(size = 0;size<MAX_PLAYERS;size++) { ingame.skScores[size][0] =0; ingame.skScores[size][1] =0; } return true; }
//////////////////////////////// // at the end of every game. bool multiGameShutdown(void) { PLAYERSTATS st; uint32_t time; debug(LOG_NET, "%s is shutting down.", getPlayerName(selectedPlayer)); sendLeavingMsg(); // say goodbye updateMultiStatsGames(); // update games played. st = getMultiStats(selectedPlayer); // save stats saveMultiStats(getPlayerName(selectedPlayer), getPlayerName(selectedPlayer), &st); // if we terminate the socket too quickly, then, it is possible not to get the leave message time = wzGetTicks(); while (wzGetTicks() - time < 1000) { wzYieldCurrentThread(); // TODO Make a wzDelay() function? } // close game NETclose(); NETremRedirects(); if (ingame.numStructureLimits) { ingame.numStructureLimits = 0; free(ingame.pStructureLimits); ingame.pStructureLimits = NULL; } ingame.flags = 0; ingame.localJoiningInProgress = false; // Clean up ingame.localOptionsReceived = false; ingame.bHostSetup = false; // Dont attempt a host ingame.TimeEveryoneIsInGame = 0; ingame.startTime = 0; NetPlay.isHost = false; bMultiPlayer = false; // Back to single player mode bMultiMessages = false; selectedPlayer = 0; // Back to use player 0 (single player friendly) return true; }
//////////////////////////////// // at the end of every game. BOOL multiGameShutdown(void) { PLAYERSTATS st; debug(LOG_NET,"%s is shutting down.",getPlayerName(selectedPlayer)); sendLeavingMsg(); // say goodbye updateMultiStatsGames(); // update games played. st = getMultiStats(selectedPlayer); // save stats saveMultiStats(getPlayerName(selectedPlayer), getPlayerName(selectedPlayer), &st); // if we terminate the socket too quickly, then, it is possible not to get the leave message SDL_Delay(1000); // close game NETclose(); NETremRedirects(); if (ingame.numStructureLimits) { ingame.numStructureLimits = 0; free(ingame.pStructureLimits); ingame.pStructureLimits = NULL; } ingame.localJoiningInProgress = false; // Clean up ingame.localOptionsReceived = false; ingame.bHostSetup = false; // Dont attempt a host NetPlay.isHost = false; bMultiPlayer = false; // Back to single player mode bMultiMessages = false; selectedPlayer = 0; // Back to use player 0 (single player friendly) return true; }
// //////////////////////////////////////////////////////////////////////////// // Load Player Stats bool loadMultiStats(char *sPlayerName, PLAYERSTATS *st) { char fileName[255]; UDWORD size; char *pFileData; *st = PLAYERSTATS(); // clear in case we don't get to load // Prevent an empty player name (where the first byte is a 0x0 terminating char already) if (!*sPlayerName) { strcpy(sPlayerName, _("Player")); } snprintf(fileName, sizeof(fileName), "%s%s.sta", MultiPlayersPath, sPlayerName); debug(LOG_WZ, "loadMultiStats: %s", fileName); // check player already exists if (PHYSFS_exists(fileName)) { if (loadFile(fileName, &pFileData, &size)) { if (strncmp(pFileData, "WZ.STA.v3", 9) != 0) { free(pFileData); pFileData = nullptr; return false; // wrong version or not a stats file } char identity[1001]; identity[0] = '\0'; sscanf(pFileData, "WZ.STA.v3\n%u %u %u %u %u\n%1000[A-Za-z0-9+/=]", &st->wins, &st->losses, &st->totalKills, &st->totalScore, &st->played, identity); free(pFileData); if (identity[0] != '\0') { st->identity.fromBytes(base64Decode(identity), EcKey::Private); } } } if (st->identity.empty()) { st->identity = EcKey::generate(); // Generate new identity. saveMultiStats(sPlayerName, sPlayerName, st); // Save new identity. } // reset recent scores st->recentKills = 0; st->recentScore = 0; // clear any skirmish stats. for (size = 0; size < MAX_PLAYERS; size++) { ingame.skScores[size][0] = 0; ingame.skScores[size][1] = 0; } return true; }