ClientSave.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <client/ClientSave.h>
00022 #include <client/ScorchedClient.h>
00023 #include <server/ScorchedServer.h>
00024 #include <tankai/TankAIStore.h>
00025 #include <tank/TankContainer.h>
00026 #include <tank/TankState.h>
00027 #include <tank/TankAvatar.h>
00028 #include <tank/TankTeamScore.h>
00029 #include <tank/TankModelContainer.h>
00030 #include <net/NetBuffer.h>
00031 #include <coms/ComsAddPlayerMessage.h>
00032 #include <coms/ComsMessageSender.h>
00033 #include <common/Defines.h>
00034 #include <common/Logger.h>
00035 #include <common/OptionsScorched.h>
00036 #include <common/OptionsTransient.h>
00037 #include <stdio.h>
00038 
00039 static NetBuffer saveBuffer;
00040 static bool stateRestoredFromFile = false;
00041 
00042 bool ClientSave::storeClient()
00043 {
00044         NetBuffer &buffer = saveBuffer;
00045         buffer.reset();
00046 
00047         // Add Version
00048         buffer.addToBuffer(S3D::ScorchedProtocolVersion);
00049         
00050         // GameState
00051         ScorchedServer::instance()->getOptionsGame().getMainOptions().writeToBuffer(buffer, true, false);
00052         
00053         // Transient State
00054         if (!ScorchedServer::instance()->getOptionsTransient().writeToBuffer(
00055                 buffer)) return false;
00056         if (!ScorchedServer::instance()->getContext().getTankTeamScore().writeMessage(
00057                 buffer)) return false;
00058         
00059         // No Players
00060         buffer.addToBuffer(ScorchedServer::instance()->getTankContainer().
00061                 getNoOfNonSpectatorTanks());
00062 
00063         // Players
00064         std::map<unsigned int, Tank *> &tanks = 
00065                 ScorchedServer::instance()->getTankContainer().
00066                         getPlayingTanks();
00067         std::map<unsigned int, Tank *>::iterator itor;
00068         for (itor = tanks.begin();
00069                 itor != tanks.end();
00070                 itor++)
00071         {
00072                 // Add each tank
00073                 Tank *tank = (*itor).second;
00074 
00075                 // Remove the spectator tank
00076                 if (!tank->getState().getSpectator())
00077                 {
00078                         // Add all other tanks
00079                         buffer.addToBuffer(tank->getPlayerId());
00080                         if (!tank->writeMessage(buffer, true)) return false;
00081                         if (!tank->getAvatar().writeMessage(buffer)) return false;
00082 
00083                         TankAI *tankAI = tank->getTankAI();
00084                         if (tankAI) 
00085                         {
00086                                 buffer.addToBuffer(tankAI->getName());
00087                         }
00088                         else
00089                         {
00090                                 buffer.addToBuffer("Human");
00091                         }
00092                 }
00093         }
00094 
00095         return true;
00096 }
00097 
00098 bool ClientSave::saveClient(const std::string &fileName)
00099 {
00100         FILE *file = fopen(fileName.c_str(), "wb");
00101         if (!file) return false;
00102 
00103         int size = fwrite(saveBuffer.getBuffer(),       
00104                 sizeof(char),
00105                 saveBuffer.getBufferUsed(),
00106                 file);
00107         fclose(file);
00108         return (size == saveBuffer.getBufferUsed());
00109 }
00110 
00111 bool ClientSave::restoreClient(bool loadGameState, bool loadPlayers)
00112 {
00113         NetBufferReader reader(saveBuffer);
00114 
00115         // Add Version
00116         std::string version;
00117         if (!reader.getFromBuffer(version)) return false;
00118         if (0 != strcmp(version.c_str(), S3D::ScorchedProtocolVersion.c_str()))
00119         {
00120                 S3D::dialogMessage("LoadGame", 
00121                         S3D::formatStringBuffer(
00122                         "ERROR: Saved file version does not match game version.\n"
00123                         "Saved version : %s\n"
00124                         "Current version : %s\n",
00125                         version.c_str(),
00126                         S3D::ScorchedProtocolVersion.c_str()));
00127                 return false;
00128         }
00129         
00130         // GameState
00131         if (loadGameState)
00132         {
00133                 if (!ScorchedServer::instance()->getOptionsGame().getMainOptions().readFromBuffer(
00134                         reader, true, false)) return false;
00135         }
00136         else
00137         {
00138                 OptionsGame optionsGame;
00139                 optionsGame.readFromBuffer(reader, true, false);
00140         }
00141         
00142         // Transient State
00143         if (!ScorchedServer::instance()->getOptionsTransient().readFromBuffer(
00144                 reader)) return false;
00145         if (!ScorchedServer::instance()->getContext().getTankTeamScore().readMessage(
00146                 reader)) return false;
00147         
00148         if (!loadPlayers) return true;
00149 
00150         bool specTanks = (ScorchedServer::instance()->getTankContainer().getNoOfTanks() -
00151                 ScorchedServer::instance()->getTankContainer().getNoOfNonSpectatorTanks() > 1);
00152 
00153         // Players
00154         int noTanks = 0;
00155         if (!reader.getFromBuffer(noTanks)) return false;
00156         for (int i=0; i<noTanks; i++)
00157         {
00158                 unsigned int playerId = 0;
00159                 if (!reader.getFromBuffer(playerId)) return false;
00160         
00161                 if (!specTanks)
00162                 {
00163                         Tank *tank = 
00164                                 ScorchedServer::instance()->getTankContainer().getTankById(playerId);
00165                         if (tank)
00166                         {
00167                                 if (!tank->readMessage(reader)) return false;
00168                                 if (!tank->getAvatar().readMessage(reader)) return false;
00169                                 std::string tankAIStr;
00170                                 if (!reader.getFromBuffer(tankAIStr)) return false;
00171                         }
00172                 }
00173                 else
00174                 {
00175                         Vector color;
00176                         Tank tank(
00177                                 ScorchedServer::instance()->getContext(),
00178                                 playerId, // PlayerId
00179                                 0, // DestinationId
00180                                 LangString(), // Name
00181                                 color,
00182                                 "",
00183                                 "");
00184                         if (!tank.readMessage(reader)) return false;
00185                         if (!tank.getAvatar().readMessage(reader)) return false;
00186                 
00187                         std::string tankAIStr;
00188                         if (!reader.getFromBuffer(tankAIStr)) return false;
00189                 
00190                         if (!tank.getState().getSpectator())
00191                         {
00192                                 ComsAddPlayerMessage message(
00193                                         tank.getPlayerId(),
00194                                         tank.getTargetName(),
00195                                         tank.getColor(),
00196                                         tank.getModelContainer().getTankModelName(),
00197                                         tank.getModelContainer().getTankTypeName(),
00198                                         ScorchedClient::instance()->getTankContainer().getCurrentDestinationId(),
00199                                         tank.getTeam(),
00200                                         tankAIStr.c_str());
00201 
00202                                 message.setPlayerIconName(tank.getAvatar().getName());
00203                                 message.getPlayerIcon().addDataToBuffer(
00204                                         tank.getAvatar().getFile().getBuffer(),
00205                                         tank.getAvatar().getFile().getBufferUsed());
00206                                 ComsMessageSender::sendToServer(message);
00207                         }
00208                 }
00209         }
00210 
00211         return true;
00212 }
00213 
00214 bool ClientSave::stateRestored()
00215 {
00216         return stateRestoredFromFile;
00217 }
00218 
00219 void ClientSave::setStateNotRestored()
00220 {
00221         stateRestoredFromFile = false;
00222 }
00223 
00224 bool ClientSave::loadClient(const std::string &fileName)
00225 {
00226         FILE *file = fopen(fileName.c_str(), "rb");
00227         if (!file) 
00228         {
00229                 Logger::log(S3D::formatStringBuffer("ERROR: File \"%s\" cannot be found.",
00230                         fileName.c_str()));
00231                 return false;
00232         }
00233 
00234         saveBuffer.reset();
00235         char buffer[2];
00236         while (0 != fread(buffer, 1, 1, file))
00237         {
00238                 saveBuffer.addDataToBuffer(buffer, 1);
00239         }
00240 
00241         fclose(file);
00242         stateRestoredFromFile = true;
00243         return true;
00244 }

Generated on Mon Feb 16 15:14:36 2009 for Scorched3D by  doxygen 1.5.3