00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <server/ServerMessageHandler.h>
00022 #include <server/ScorchedServer.h>
00023 #include <server/ScorchedServerUtil.h>
00024 #include <server/ServerCommon.h>
00025 #include <server/ServerBanned.h>
00026 #include <server/ServerKeepAliveHandler.h>
00027 #include <server/ServerChannelManager.h>
00028 #include <server/ServerState.h>
00029 #include <tank/TankDeadContainer.h>
00030 #include <tank/TankState.h>
00031 #include <tank/TankContainer.h>
00032 #include <tankai/TankAIStore.h>
00033 #include <coms/ComsRmPlayerMessage.h>
00034 #include <coms/ComsMessageSender.h>
00035 #include <net/NetInterface.h>
00036 #include <common/Logger.h>
00037 #include <common/OptionsScorched.h>
00038 #include <common/StatsLogger.h>
00039
00040 ServerMessageHandler::DestinationInfo::DestinationInfo() :
00041 adminTries(0), admin(false)
00042 {
00043 }
00044
00045 ServerMessageHandler::DestinationInfo *ServerMessageHandler::getDestinationInfo(unsigned int destinationId)
00046 {
00047 std::map<unsigned int, DestinationInfo>::iterator itor =
00048 destinationInfos_.find(destinationId);
00049 if (itor == destinationInfos_.end()) return 0;
00050 return &itor->second;
00051 }
00052
00053 ServerMessageHandler *ServerMessageHandler::instance_ = 0;
00054
00055 ServerMessageHandler *ServerMessageHandler::instance()
00056 {
00057 if (!instance_)
00058 {
00059 instance_ = new ServerMessageHandler;
00060 }
00061 return instance_;
00062 }
00063
00064 ServerMessageHandler::ServerMessageHandler()
00065 {
00066 }
00067
00068 ServerMessageHandler::~ServerMessageHandler()
00069 {
00070 }
00071
00072 void ServerMessageHandler::messageRecv(unsigned int destinationId)
00073 {
00074 ServerKeepAliveHandler::instance()->keepAlive(destinationId);
00075 }
00076
00077 void ServerMessageHandler::messageSent(unsigned int destinationId)
00078 {
00079 }
00080
00081 void ServerMessageHandler::clientConnected(NetMessage &message)
00082 {
00083
00084 if (message.getIpAddress() != 0 &&
00085 ScorchedServerUtil::instance()->bannedPlayers.getBanned(message.getIpAddress()) ==
00086 ServerBanned::Banned)
00087 {
00088 Logger::log(S3D::formatStringBuffer("Banned client connected dest=\"%i\" ip=\"%s\"",
00089 message.getDestinationId(),
00090 NetInterface::getIpName(message.getIpAddress())));
00091 ScorchedServer::instance()->getNetInterface().
00092 disconnectClient(message.getDestinationId());
00093 return;
00094 }
00095
00096
00097 std::map<unsigned int, Tank *> &playingTanks =
00098 ScorchedServer::instance()->getTankContainer().getPlayingTanks();
00099 std::map<unsigned int, Tank *>::iterator playingItor;
00100 for (playingItor = playingTanks.begin();
00101 playingItor != playingTanks.end();
00102 playingItor++)
00103 {
00104 Tank *current = (*playingItor).second;
00105 if (current->getDestinationId() == message.getDestinationId())
00106 {
00107 Logger::log(S3D::formatStringBuffer("Duplicate connection from destination \"%i\"",
00108 message.getDestinationId()));
00109 ScorchedServer::instance()->getNetInterface().
00110 disconnectClient(message.getDestinationId());
00111 return;
00112 }
00113
00114 if (!ScorchedServer::instance()->getOptionsGame().getAllowSameIP() &&
00115 message.getIpAddress() != 0)
00116 {
00117 if (message.getIpAddress() == current->getIpAddress())
00118 {
00119 Logger::log(S3D::formatStringBuffer("Duplicate ip connection from ip address \"%s\"",
00120 NetInterface::getIpName(message.getIpAddress())));
00121 ScorchedServer::instance()->getNetInterface().
00122 disconnectClient(message.getDestinationId());
00123 return;
00124 }
00125 }
00126 }
00127
00128
00129 destinationInfos_[message.getDestinationId()] = DestinationInfo();
00130
00131 Logger::log(S3D::formatStringBuffer("Client connected dest=\"%i\" ip=\"%s\"",
00132 message.getDestinationId(),
00133 NetInterface::getIpName(message.getIpAddress())));
00134 }
00135
00136 void ServerMessageHandler::clientDisconnected(NetMessage &message)
00137 {
00138 const char *reason = "Unknown";
00139 if (message.getFlags() == NetMessage::UserDisconnect) reason = "User";
00140 else if (message.getFlags() == NetMessage::KickDisconnect) reason = "Kicked";
00141 else if (message.getFlags() == NetMessage::TimeoutDisconnect) reason = "Timeout";
00142
00143 Logger::log(S3D::formatStringBuffer("Client disconnected dest=\"%i\" ip=\"%s\" reason=\"%s\"",
00144 message.getDestinationId(),
00145 NetInterface::getIpName(message.getIpAddress()),
00146 reason));
00147
00148
00149 std::list<unsigned int> removePlayers;
00150 unsigned int destinationId = message.getDestinationId();
00151 std::map<unsigned int, Tank *>::iterator itor;
00152 std::map<unsigned int, Tank *> &tanks =
00153 ScorchedServer::instance()->getTankContainer().getPlayingTanks();
00154 for (itor = tanks.begin();
00155 itor != tanks.end();
00156 itor++)
00157 {
00158 Tank *tank = (*itor).second;
00159 if (tank->getDestinationId() == destinationId)
00160 {
00161 removePlayers.push_back(tank->getPlayerId());
00162 }
00163 }
00164
00165
00166 std::list<unsigned int>::iterator remItor;
00167 for (remItor = removePlayers.begin();
00168 remItor != removePlayers.end();
00169 remItor++)
00170 {
00171 unsigned int playerId = *remItor;
00172 destroyPlayer(playerId, reason);
00173 }
00174
00175
00176 ServerChannelManager::instance()->destinationDisconnected(message.getDestinationId());
00177
00178
00179 destinationInfos_.erase(message.getDestinationId());
00180 }
00181
00182 void ServerMessageHandler::destroyPlayer(unsigned int tankId, const char *reason)
00183 {
00184
00185 Tank *tank = ScorchedServer::instance()->getTankContainer().getTankById(tankId);
00186 if (!tank)
00187 {
00188 Logger::log(S3D::formatStringBuffer("Unknown player disconnected id=\"%i\" (%s)",
00189 tankId, reason));
00190 return;
00191 }
00192
00193
00194 Logger::log(
00195 S3D::formatStringBuffer("Player disconnected dest=\"%i\" id=\"%i\" name=\"%s\" reason=\"%s\"",
00196 tank->getDestinationId(),
00197 tankId,
00198 tank->getCStrName().c_str(),
00199 reason));
00200 ServerChannelManager::instance()->sendText(
00201 ChannelText("info",
00202 "PLAYER_DISCONNECTED",
00203 "Player disconnected \"{0}\" ({1})",
00204 tank->getTargetName(), reason),
00205 true);
00206
00207
00208 if (tank->getState().getState() == TankState::sNormal &&
00209 ScorchedServer::instance()->getGameState().getState() == ServerState::ServerStateShot)
00210 {
00211
00212 ScorchedServer::instance()->getTankDeadContainer().addTank(tank);
00213
00214
00215 tank->getState().setDestroy(true);
00216
00217
00218 if (tank->getDestinationId() != 0)
00219 {
00220 TankAI *ai = ScorchedServer::instance()->getTankAIs().getAIByName("Random");
00221 tank->setTankAI(ai->createCopy(tank));
00222 tank->setDestinationId(0);
00223 tank->setKeepAlive(0);
00224 }
00225 }
00226 else
00227 {
00228
00229 actualDestroyPlayer(tankId);
00230 }
00231 }
00232
00233 void ServerMessageHandler::destroyTaggedPlayers()
00234 {
00235 std::map<unsigned int, Tank *> tanks =
00236 ScorchedServer::instance()->getTankContainer().getAllTanks();
00237 std::map<unsigned int, Tank *>::iterator itor;
00238 for (itor = tanks.begin();
00239 itor != tanks.end();
00240 itor++)
00241 {
00242 Tank *tank = itor->second;
00243 if (tank->getState().getDestroy())
00244 {
00245 actualDestroyPlayer(tank->getPlayerId());
00246 }
00247 }
00248 }
00249
00250 void ServerMessageHandler::actualDestroyPlayer(unsigned int tankId)
00251 {
00252
00253 Tank *tank = ScorchedServer::instance()->getTankContainer().removeTank(tankId);
00254 if (!tank) return;
00255
00256 StatsLogger::instance()->tankDisconnected(tank);
00257
00258
00259 ComsRmPlayerMessage rmPlayerMessage(
00260 tankId);
00261 ComsMessageSender::sendToAllConnectedClients(rmPlayerMessage);
00262
00263
00264 ScorchedServer::instance()->getTankDeadContainer().addTank(tank);
00265 delete tank;
00266 }
00267
00268 void ServerMessageHandler::clientError(NetMessage &message,
00269 const char *errorString)
00270 {
00271 Logger::log(S3D::formatStringBuffer("Client \"%i\", ***Server Error*** \"%s\"",
00272 message.getDestinationId(),
00273 errorString));
00274 ServerCommon::kickDestination(message.getDestinationId());
00275 }