ServerAdminHandler.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 <server/ServerAdminHandler.h>
00022 #include <server/ScorchedServer.h>
00023 #include <server/ScorchedServerUtil.h>
00024 #include <server/ServerChannelManager.h>
00025 #include <server/ServerCommon.h>
00026 #include <server/ServerAdminCommon.h>
00027 #include <server/ServerAdminSessions.h>
00028 #include <server/ServerMessageHandler.h>
00029 #include <common/StatsLogger.h>
00030 #include <common/Logger.h>
00031 #include <common/Defines.h>
00032 #include <coms/ComsAdminMessage.h>
00033 #include <coms/ComsAdminResultMessage.h>
00034 #include <coms/ComsSyncCheckMessage.h>
00035 #include <coms/ComsMessageSender.h>
00036 #include <net/NetInterface.h>
00037 #include <tank/TankContainer.h>
00038 #include <tank/TankState.h>
00039 #include <stdlib.h>
00040 
00041 ServerAdminHandler *ServerAdminHandler::instance()
00042 {
00043         static ServerAdminHandler *instance = 
00044                 new ServerAdminHandler;
00045         return instance;
00046 }
00047 
00048 ServerAdminHandler::ServerAdminHandler()
00049 {
00050         ScorchedServer::instance()->getComsMessageHandler().addHandler(
00051                 "ComsAdminMessage",
00052                 this);
00053 }
00054 
00055 ServerAdminHandler::~ServerAdminHandler()
00056 {
00057 }
00058 
00059 bool ServerAdminHandler::processMessage(
00060         NetMessage &netMessage,
00061         const char *messageType,
00062         NetBufferReader &reader)
00063 {
00064         ComsAdminMessage message;
00065         if (!message.readMessage(reader)) return false;
00066 
00067         unsigned int destinationId = netMessage.getDestinationId();
00068 
00069         ServerMessageHandler::DestinationInfo *destinationInfo =
00070                 ServerMessageHandler::instance()->getDestinationInfo(destinationId);
00071         if (!destinationInfo) return false;
00072 
00073         // Check if the SID is valid
00074         ServerAdminSessions::SessionParams *adminSession =
00075                 ServerAdminSessions::instance()->getSession(message.getSid());
00076 
00077         // Check if we are logging in
00078         if (message.getType() == ComsAdminMessage::AdminLogin ||
00079                 message.getType() == ComsAdminMessage::AdminLoginLocal)
00080         {       
00081                 unsigned int sid = message.getSid();
00082                 if (adminSession ||
00083                         (sid = ServerAdminSessions::instance()->
00084                                 login(message.getParam1(), message.getParam2(),
00085                                 NetInterface::getIpName(netMessage.getIpAddress()))) != 0)
00086                 {
00087                         adminSession =
00088                                 ServerAdminSessions::instance()->getSession(sid);
00089 
00090                         ServerChannelManager::instance()->refreshDestination(destinationId);
00091 
00092                         ServerChannelManager::instance()->sendText(
00093                                 ChannelText("info", "ADMIN_LOGGED_IN", 
00094                                         "Server admin \"{0}\" logged in",
00095                                         adminSession->credentials.username),
00096                                 true);
00097                         ServerCommon::serverLog(
00098                                 S3D::formatStringBuffer(
00099                                         "Server admin \"%s\" logged in, destination id \"%u\"",
00100                                 adminSession->credentials.username.c_str(),
00101                                 destinationId));
00102 
00103                         ComsAdminResultMessage resultMessage(sid, message.getType());
00104                         ComsMessageSender::sendToSingleClient(resultMessage, destinationId);
00105                         destinationInfo->admin = true;
00106                         destinationInfo->adminTries = 0;
00107 
00108                         return true;
00109                 }
00110                 else
00111                 {
00112                         if (message.getType() != ComsAdminMessage::AdminLoginLocal)
00113                         {
00114                                 destinationInfo->adminTries++;
00115                                 
00116                                 ServerChannelManager::instance()->sendText(
00117                                         ChannelText("info", 
00118                                                 "INCORRECT_PASSWORD",
00119                                                 "Incorrect admin password (try {0}/3)", 
00120                                                 destinationInfo->adminTries),
00121                                         destinationId,
00122                                         true);
00123                                 if (destinationInfo->adminTries > 3)
00124                                 {
00125                                         ServerCommon::kickDestination(destinationId);
00126                                 }
00127 
00128                                 Logger::log(S3D::formatStringBuffer(
00129                                         "Failed login for server admin \"%s\" via console, ip \"%s\", destination id \"%u\"",
00130                                         message.getParam1(),
00131                                         NetInterface::getIpName(netMessage.getIpAddress()),
00132                                         destinationId));
00133                         }
00134 
00135                         ComsAdminResultMessage resultMessage(0, message.getType());
00136                         ComsMessageSender::sendToSingleClient(resultMessage, destinationId);
00137                         destinationInfo->admin = false;
00138 
00139                         return true;
00140                 }
00141         }
00142 
00143         if (!adminSession)
00144         {
00145                 ServerChannelManager::instance()->sendText(
00146                         ChannelText("info", "ADMIN_NOT_LOGGED_IN", 
00147                                 "You are not logged in as admin"),
00148                         destinationId,
00149                         false);
00150 
00151                 ComsAdminResultMessage resultMessage(0, message.getType());
00152                 ComsMessageSender::sendToSingleClient(resultMessage, destinationId);
00153                 destinationInfo->admin = false;
00154 
00155                 return true;    
00156         }
00157         const char *adminName = adminSession->credentials.username.c_str();
00158 
00159         // Do admin fn (we are logged in at this point)
00160         switch (message.getType())
00161         {
00162         case ComsAdminMessage::AdminShow:
00163                 {
00164                         std::map<unsigned int, Tank *> &tanks = 
00165                                 ScorchedServer::instance()->getTankContainer().getAllTanks();
00166                         std::string result;
00167                         result += 
00168                                 "--Admin Show-----------------------------------------\n";
00169                         std::map<unsigned int, Tank *>::iterator itor;
00170                         for (itor = tanks.begin();
00171                                 itor != tanks.end();
00172                                 itor++)
00173                         {
00174                                 Tank *tank = (*itor).second;
00175 
00176                                 result += 
00177                                         S3D::formatStringBuffer("%i \"%s\" \"%s\" \"%u\" %s \n",
00178                                                 tank->getPlayerId(), 
00179                                                 tank->getCStrName().c_str(),
00180                                                 NetInterface::getIpName(tank->getIpAddress()),
00181                                                 StatsLogger::instance()->getStatsId(tank->getUniqueId()),
00182                                                 (tank->getState().getMuted()?"Muted":"Not Muted"));
00183                         }
00184                         result +=
00185                                 "-----------------------------------------------------\n";
00186 
00187                         ServerChannelManager::instance()->sendText( 
00188                                 ChannelText("info", LANG_STRING(result)),
00189                                 destinationId,
00190                                 false);
00191                 }
00192                 break;
00193         case ComsAdminMessage::AdminLogout:
00194                 {
00195                         ServerChannelManager::instance()->sendText( 
00196                                 ChannelText("info", "ADMIN_LOGGED_OUT", 
00197                                         "Server admin \"{0}\" logged out",
00198                                         adminName),
00199                                 true);
00200                         ServerCommon::serverLog(
00201                                 S3D::formatStringBuffer("Server admin \"%s\" logged out",
00202                                 adminName));
00203 
00204                         ServerAdminSessions::instance()->logout(message.getSid());
00205                         ServerChannelManager::instance()->refreshDestination(destinationId);
00206 
00207                         ComsAdminResultMessage resultMessage(0, message.getType());
00208                         ComsMessageSender::sendToSingleClient(resultMessage, destinationId);
00209                         destinationInfo->admin = false;
00210                 }
00211                 break;
00212         case ComsAdminMessage::AdminShowBanned:
00213                 {
00214                         std::string result;
00215                         result += 
00216                                 "--Admin Show Banned----------------------------------\n";
00217 
00218                         std::list<ServerBanned::BannedRange> &bannedIps = 
00219                                 ScorchedServerUtil::instance()->bannedPlayers.getBannedIps();
00220                         std::list<ServerBanned::BannedRange>::iterator itor;
00221                         for (itor = bannedIps.begin();
00222                                 itor != bannedIps.end();
00223                                 itor++)
00224                         {
00225                                 ServerBanned::BannedRange &range = (*itor);
00226                                 std::string mask = NetInterface::getIpName(range.mask);
00227 
00228                                 std::map<unsigned int, ServerBanned::BannedEntry>::iterator ipitor;
00229                                 for (ipitor = range.ips.begin();
00230                                         ipitor != range.ips.end();
00231                                         ipitor++)
00232                                 {
00233                                         unsigned int ip = (*ipitor).first;
00234                                         ServerBanned::BannedEntry &entry = (*ipitor).second;
00235                                         std::string ipName = NetInterface::getIpName(ip);
00236                                         std::string name = LangStringUtil::convertFromLang(entry.name);
00237 
00238                                         result += S3D::formatStringBuffer("\"%s:%s:%s\" %s %s (%s) - %s",
00239                                                 name.c_str(),
00240                                                 entry.uniqueid.c_str(),
00241                                                 entry.SUI.c_str(),
00242                                                 ServerBanned::getBannedTypeStr(entry.type),
00243                                                 ipName.c_str(), mask.c_str(),
00244                                                 (entry.bantime?ctime(&entry.bantime):"\n"));
00245                                 }
00246                         }
00247                         result +=
00248                                 "-----------------------------------------------------\n";
00249 
00250                         ServerChannelManager::instance()->sendText( 
00251                                 ChannelText("info", LANG_STRING(result)),
00252                                 destinationId, 
00253                                 false);
00254                 }
00255                 break;
00256         case ComsAdminMessage::AdminBan:
00257                 {
00258                         if (!ServerAdminCommon::banPlayer(
00259                                 adminSession->credentials,
00260                                 atoi(message.getParam1()), "<via console>"))
00261                         {
00262                                 ServerChannelManager::instance()->sendText( 
00263                                         ChannelText("info", 
00264                                                 "UNKNOWN_PLAYER_BAN", 
00265                                                 "Unknown player for ban"),
00266                                         destinationId,
00267                                         false);
00268                         }
00269                 }
00270                 break;
00271         case ComsAdminMessage::AdminFlag:
00272                 {
00273                         if (!ServerAdminCommon::flagPlayer(
00274                                 adminSession->credentials,
00275                                 atoi(message.getParam1()), "<via console>"))
00276                         {
00277                                 ServerChannelManager::instance()->sendText( 
00278                                         ChannelText("info",
00279                                                 "UNKNOWN_PLAYER_FLAG",
00280                                                 "Unknown player for flag"),
00281                                         destinationId,
00282                                         false);
00283                         }
00284                 }
00285                 break;
00286         case ComsAdminMessage::AdminPoor:
00287                 {
00288                         if (!ServerAdminCommon::poorPlayer(
00289                                 adminSession->credentials,
00290                                 atoi(message.getParam1())))
00291                         {
00292                                 ServerChannelManager::instance()->sendText( 
00293                                         ChannelText("info",
00294                                                 "UNKNOWN_PLAYER_POOR",
00295                                                 "Unknown player for poor"),
00296                                         destinationId,
00297                                         false);
00298                         }
00299                 }
00300                 break;  
00301         case ComsAdminMessage::AdminKick:
00302                 {
00303                         if (!ServerAdminCommon::kickPlayer(
00304                                 adminSession->credentials,
00305                                 atoi(message.getParam1())))
00306                         {
00307                                 ServerChannelManager::instance()->sendText( 
00308                                         ChannelText("info", 
00309                                                 "UNKNOWN_PLAYER_KICK",
00310                                                 "Unknown player for kick"),
00311                                         destinationId,
00312                                         false);
00313                         }
00314                 }
00315                 break;
00316         case ComsAdminMessage::AdminMute:
00317         case ComsAdminMessage::AdminUnMute:
00318                 {
00319                         bool mute = (message.getType() == ComsAdminMessage::AdminMute);
00320                         if (!ServerAdminCommon::mutePlayer(
00321                                 adminSession->credentials,
00322                                 atoi(message.getParam1()), mute))
00323                         {
00324                                 ServerChannelManager::instance()->sendText( 
00325                                         ChannelText("info",
00326                                                 "UNKNOWN_PLAYER_MUTE",
00327                                                 "Unknown player for mute"),
00328                                         destinationId,
00329                                         false);
00330                         }       
00331                 }
00332                 break;
00333         case ComsAdminMessage::AdminPermMute:
00334                 {
00335                         if (!ServerAdminCommon::permMutePlayer(
00336                                 adminSession->credentials,
00337                                 atoi(message.getParam1()), "<via console>"))
00338                         {
00339                                 ServerChannelManager::instance()->sendText( 
00340                                         ChannelText("info",
00341                                                 "UNKNOWN_PLAYER_PERMMUTE",
00342                                                 "Unknown player for permmute"),
00343                                         destinationId,
00344                                         false);
00345                         }       
00346                 }
00347                 break;
00348         case ComsAdminMessage::AdminUnPermMute:
00349                 {
00350                         if (!ServerAdminCommon::unpermMutePlayer(
00351                                 adminSession->credentials,
00352                                 atoi(message.getParam1())))
00353                         {
00354                                 ServerChannelManager::instance()->sendText( 
00355                                         ChannelText("info",
00356                                                 "UNKNOWN_PLAYER_UNPERMMUTE",
00357                                                 "Unknown player for unpermmute"),
00358                                         destinationId,
00359                                         false);
00360                         }
00361                 }
00362                 break;
00363         case ComsAdminMessage::AdminTalk:
00364                 ServerAdminCommon::adminSay(adminSession->credentials, "info", message.getParam1());
00365                 break;
00366         case ComsAdminMessage::AdminAdminTalk:
00367                 ServerAdminCommon::adminSay(adminSession->credentials, "admin", message.getParam1());
00368                 break;
00369         case ComsAdminMessage::AdminMessage:
00370                 ServerAdminCommon::adminSay(adminSession->credentials, "banner", message.getParam1());
00371                 break;
00372         case ComsAdminMessage::AdminSyncCheck:
00373                 {
00374                         ServerChannelManager::instance()->sendText( 
00375                                 ChannelText("info", "SENDING_SYNC", "sending sync..."),
00376                                 destinationId, true);
00377                         ComsSyncCheckMessage syncCheck;
00378                         ComsMessageSender::sendToSingleClient(syncCheck, destinationId);
00379                 }
00380                 break;
00381         case ComsAdminMessage::AdminKillAll:
00382                 ServerAdminCommon::killAll(adminSession->credentials);
00383                 break;
00384         case ComsAdminMessage::AdminNewGame:
00385                 ServerAdminCommon::newGame(adminSession->credentials);
00386                 break;  
00387         case ComsAdminMessage::AdminSlap:
00388                 {
00389                         if (!ServerAdminCommon::slapPlayer(
00390                                 adminSession->credentials,
00391                                 atoi(message.getParam1()), (float) atof(message.getParam2())))
00392                         {
00393                                 ServerChannelManager::instance()->sendText( 
00394                                         ChannelText("info", 
00395                                                 "UNKNOWN_PLAYER_SLAP", 
00396                                                 "Unknown player for slap"),
00397                                         destinationId, false);
00398                         }
00399                 }
00400                 break;
00401         case ComsAdminMessage::AdminAdd:
00402                 {
00403                         if (!ServerAdminCommon::addPlayer(
00404                                 adminSession->credentials,
00405                                 message.getParam1()))
00406                         {
00407                                 ServerChannelManager::instance()->sendText( 
00408                                         ChannelText("info",
00409                                                 "UNKNOWN_PLAYER_ADD",
00410                                                 "Unknown player type to add"),
00411                                         destinationId, false);
00412                         }       
00413                 }
00414                 break;
00415         }
00416 
00417         return true;
00418 }

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