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