//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // Scorched3D is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static FileLogger *serverFileLogger = 0; void ServerCommon::startFileLogger() { if (!serverFileLogger) { char buffer[256]; snprintf(buffer, 256, "ServerLog-%i-", ScorchedServer::instance()->getOptionsGame().getPortNo()); serverFileLogger = new FileLogger(buffer); if (0 != strcmp(ScorchedServer::instance()->getOptionsGame(). getServerFileLogger(), "none")) { Logger::addLogger(serverFileLogger); Logger::log( "Created file logger."); } else { Logger::log( "Not created file logger."); } } } void ServerCommon::sendStringMessage(unsigned int dest, const char *text, bool blogMessage) { // Remove any bad characters for (char *r = (char *) text; *r; r++) { if (*r == '%') *r = ' '; if (*r < 0) *r = ' '; } if (blogMessage) { const char *logMessage = formatString("Messages : %s", text); ServerTextHandler::instance()->addMessage(logMessage); ServerCommon::serverLog(logMessage); } ComsTextMessage message(text, 0, true); if (dest == 0) { ComsMessageSender::sendToAllConnectedClients(message); } else { ComsMessageSender::sendToSingleClient(message, dest); } } void ServerCommon::sendString(unsigned int dest, const char *text, bool blogMessage) { // Remove any bad characters for (char *r = (char *) text; *r; r++) { if (*r == '%') *r = ' '; if (*r < 0) *r = ' '; } if (blogMessage) { const char *logMessage = formatString("Says : %s", text); ServerTextHandler::instance()->addMessage(logMessage); ServerCommon::serverLog(logMessage); } ComsTextMessage message(text); if (dest == 0) { ComsMessageSender::sendToAllConnectedClients(message); } else { ComsMessageSender::sendToSingleClient(message, dest); } } void ServerCommon::sendStringAdmin(const char *text) { // Remove any bad characters for (char *r = (char *) text; *r; r++) { if (*r == '%') *r = ' '; if (*r < 0) *r = ' '; } const char *logMessage = formatString("Admin Says : %s", text); ServerTextHandler::instance()->addMessage(logMessage); ServerCommon::serverLog(logMessage); std::map &tanks = ScorchedServer::instance()-> getTankContainer().getPlayingTanks(); std::map::iterator itor; for (itor = tanks.begin(); itor != tanks.end(); itor++) { Tank *tank = (*itor).second; if (tank->getState().getAdmin()) { ServerCommon::sendString( tank->getDestinationId(), formatString("(Admin) %s", text), false); } } } void ServerCommon::poorPlayer(unsigned int playerId) { Tank *tank = ScorchedServer::instance()-> getTankContainer().getTankById(playerId); if (tank) { ServerCommon::sendString(0, formatString("admin poor \"%s\"", tank->getName())); tank->getScore().setMoney(0); } } void ServerCommon::slapPlayer(unsigned int playerId, float slap) { Logger::log(formatString("Slapping player \"%i\" %.0f", playerId, slap)); Tank *tank = ScorchedServer::instance()-> getTankContainer().getTankById(playerId); if (tank) { tank->getLife().setLife( tank->getLife().getLife() - slap); sendString(0, formatString("Slapping player \"%s\" %.0f", tank->getName(), slap)); } } void ServerCommon::kickDestination(unsigned int destinationId, bool delayed) { Logger::log(formatString("Kicking destination \"%i\"", destinationId)); bool kickedPlayers = false; std::map::iterator itor; std::map tanks = ScorchedServer::instance()->getTankContainer().getPlayingTanks(); for (itor = tanks.begin(); itor != tanks.end(); itor++) { Tank *tank = (*itor).second; if (tank->getDestinationId() == destinationId) { kickedPlayers = true; kickPlayer(tank->getPlayerId()); } } // Make sure we disconnect even if a player has not been created yet if (!kickedPlayers) { ScorchedServer::instance()->getNetInterface(). disconnectClient(destinationId, delayed); } } void ServerCommon::kickPlayer(unsigned int playerId) { Logger::log(formatString("Kicking player \"%i\"", playerId)); Tank *tank = ScorchedServer::instance()-> getTankContainer().getTankById(playerId); if (tank) { sendString(0, formatString( "Player \"%s\" has been kicked from the server", tank->getName(), tank->getPlayerId())); Logger::log(formatString("Kicking client \"%s\" \"%i\"", tank->getName(), tank->getPlayerId())); if (tank->getDestinationId() == 0) { ServerMessageHandler::instance()-> destroyPlayer(tank->getPlayerId()); } else { // Cannot delay kick a player as the rest of the code // may expect him to have gone (when he is still there delayed) // and try to send messages to him ScorchedServer::instance()->getNetInterface(). disconnectClient(tank->getDestinationId()); ScorchedServer::instance()->getNetInterface().processMessages(); } } } void ServerCommon::banPlayer(unsigned int playerId, ServerBanned::BannedType type) { Tank *tank = ScorchedServer::instance()-> getTankContainer().getTankById(playerId); if (tank) { if (tank->getDestinationId() == 0) { Logger::log( "Cannot ban local player/bot"); return; } unsigned int ipAddress = tank->getIpAddress(); if (ipAddress != 0) { switch (type) { case ServerBanned::Banned: Logger::log(formatString("Banning player %i", playerId)); break; case ServerBanned::Muted: Logger::log(formatString("Perminantly muting player %i", playerId)); break; case ServerBanned::NotBanned: Logger::log(formatString("Unbanning player %i", playerId)); break; case ServerBanned::Flagged: Logger::log(formatString("Flagging player %i", playerId)); break; } ScorchedServerUtil::instance()->bannedPlayers. addBanned(ipAddress, tank->getName(), tank->getUniqueId(), type); if (type == ServerBanned::Banned) { kickPlayer(playerId); ServerAuthHandler *authHandler = ScorchedServerUtil::instance()->getAuthHandler(); if (authHandler) { authHandler->banUser(tank->getUniqueId()); } } } } } void ServerCommon::killAll() { Logger::log("Killing all players"); std::map::iterator itor; std::map &tanks = ScorchedServer::instance()->getTankContainer().getAllTanks(); for (itor = tanks.begin(); itor != tanks.end(); itor++) { Tank *current = (*itor).second; if (current->getState().getState() == TankState::sNormal) { current->getState().setState(TankState::sDead); current->getState().setLives(0); } } } void ServerCommon::startNewGame() { killAll(); Logger::log("Starting a new game"); ScorchedServer::instance()->getOptionsTransient().startNewGame(); } void ServerCommon::serverLog(const char *text) { if (OptionsParam::instance()->getDedicatedServer()) { Logger::log(text); } }