1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2011
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ////////////////////////////////////////////////////////////////////////////////
20
21 #include <server/ServerCommon.h>
22 #include <server/ScorchedServer.h>
23 #include <server/ServerMessageHandler.h>
24 #include <server/ServerChannelManager.h>
25 #include <server/ServerDestinations.h>
26 #include <target/TargetContainer.h>
27 #include <target/TargetLife.h>
28 #include <tank/Tank.h>
29 #include <tank/TankState.h>
30 #include <tank/TankScore.h>
31 #include <common/OptionsScorched.h>
32 #include <common/OptionsTransient.h>
33 #include <common/Logger.h>
34 #include <common/FileLogger.h>
35 #include <common/Defines.h>
36 #include <coms/ComsMessageSender.h>
37 #include <coms/ComsConnectRejectMessage.h>
38 #include <net/NetInterface.h>
39
40 static FileLogger *serverFileLogger = 0;
41
startFileLogger(const std::string & settingsFile)42 void ServerCommon::startFileLogger(const std::string &settingsFile)
43 {
44 if (!serverFileLogger)
45 {
46 OptionsGame optionsGame;
47 optionsGame.readOptionsFromFile(settingsFile);
48
49 char buffer[256];
50 snprintf(buffer, 256, "ServerLog-%i-", optionsGame.getPortNo());
51
52 serverFileLogger = new FileLogger(buffer);
53 if (0 != strcmp(optionsGame.getServerFileLogger(), "none"))
54 {
55 Logger::addLogger(serverFileLogger);
56 Logger::log( "Created file logger.");
57 }
58 else
59 {
60 Logger::log( "Not created file logger.");
61 }
62 }
63 }
64
kickDestination(unsigned int destinationId,const std::string & message)65 void ServerCommon::kickDestination(unsigned int destinationId,
66 const std::string &message)
67 {
68 Logger::log(S3D::formatStringBuffer("Kicking destination \"%i\" %s",
69 destinationId, message.c_str()));
70
71 bool kickedPlayers = false;
72 std::map<unsigned int, Tank *>::iterator itor;
73 std::map<unsigned int, Tank *> tanks =
74 ScorchedServer::instance()->getTargetContainer().getTanks();
75 for (itor = tanks.begin();
76 itor != tanks.end();
77 ++itor)
78 {
79 Tank *tank = (*itor).second;
80 if (tank->getDestinationId() == destinationId)
81 {
82 kickedPlayers = true;
83 kickPlayer(tank->getPlayerId(), message);
84 }
85 }
86
87 // Make sure we disconnect even if a player has not been created yet
88 if (!kickedPlayers)
89 {
90 // Form the disconnect reason
91 ComsConnectRejectMessage rejectMessage(message.c_str());
92 NetBuffer netBuffer;
93 rejectMessage.writeTypeMessage(netBuffer);
94 rejectMessage.writeMessage(netBuffer);
95 netBuffer.addToBuffer(false);
96
97 // Disconnect client
98 ScorchedServer::instance()->getNetInterface().
99 disconnectClient(netBuffer, destinationId);
100 ScorchedServer::instance()->getNetInterface().processMessages();
101 }
102 }
103
kickPlayer(unsigned int playerId,const std::string & message)104 void ServerCommon::kickPlayer(unsigned int playerId,
105 const std::string &message)
106 {
107 Logger::log(S3D::formatStringBuffer("Kicking player \"%i\" %s", playerId, message.c_str()));
108
109 Tank *tank = ScorchedServer::instance()->
110 getTargetContainer().getTankById(playerId);
111 if (tank)
112 {
113 ScorchedServer::instance()->getServerChannelManager().sendText(ChannelText("info",
114 "ADMIN_PLAYER_KICKED",
115 "[p:{0}] has been kicked from the server",
116 tank->getTargetName()), true);
117 Logger::log(S3D::formatStringBuffer("Kicking client \"%s\" \"%i\"",
118 tank->getCStrName().c_str(), tank->getPlayerId()));
119
120 // Check to see if the destination exists
121 // It may not if the tank is an AI, or if something has gone wrong when creating the tank
122 // at least this way we can always kick it
123 ServerDestination *destination =
124 ScorchedServer::instance()->getServerDestinations().getDestination(tank->getDestinationId());
125 if (!destination)
126 {
127 ScorchedServer::instance()->getServerMessageHandler().
128 destroyPlayer(tank->getPlayerId(), message.c_str());
129 }
130 else
131 {
132 // Form the disconnect reason
133 ComsConnectRejectMessage rejectMessage(message.c_str());
134 NetBuffer netBuffer;
135 rejectMessage.writeTypeMessage(netBuffer);
136 rejectMessage.writeMessage(netBuffer);
137 netBuffer.addToBuffer(false);
138
139 // Disconnect Client
140 ScorchedServer::instance()->getNetInterface().
141 disconnectClient(netBuffer, tank->getDestinationId());
142 ScorchedServer::instance()->getNetInterface().processMessages();
143 }
144 }
145 }
146
getExitEmpty()147 bool &ServerCommon::getExitEmpty()
148 {
149 static bool exitEmpty = false;
150 return exitEmpty;
151 }
152
serverLog(const std::string & text)153 void ServerCommon::serverLog(const std::string &text)
154 {
155 #ifdef S3D_SERVER
156 {
157 Logger::log(text);
158 }
159 #endif
160 }
161