00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00048 buffer.addToBuffer(S3D::ScorchedProtocolVersion);
00049
00050
00051 ScorchedServer::instance()->getOptionsGame().getMainOptions().writeToBuffer(buffer, true, false);
00052
00053
00054 if (!ScorchedServer::instance()->getOptionsTransient().writeToBuffer(
00055 buffer)) return false;
00056 if (!ScorchedServer::instance()->getContext().getTankTeamScore().writeMessage(
00057 buffer)) return false;
00058
00059
00060 buffer.addToBuffer(ScorchedServer::instance()->getTankContainer().
00061 getNoOfNonSpectatorTanks());
00062
00063
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
00073 Tank *tank = (*itor).second;
00074
00075
00076 if (!tank->getState().getSpectator())
00077 {
00078
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
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
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
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
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,
00179 0,
00180 LangString(),
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 }