ComsMessageSender.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 <coms/ComsMessageSender.h>
00022 #include <coms/ComsMessageHandler.h>
00023 #include <net/NetBuffer.h>
00024 #include <net/NetInterface.h>
00025 #include <common/Defines.h>
00026 #include <common/Logger.h>
00027 #include <tank/TankContainer.h>
00028 #include <tank/TankState.h>
00029 #ifndef S3D_SERVER
00030 #include <client/ScorchedClient.h>
00031 #endif
00032 #include <server/ScorchedServer.h>
00033 #include <set>
00034 #include <zlib.h>
00035 
00036 static NetBuffer defaultBuffer;
00037 
00038 bool ComsMessageSender::formMessage(ComsMessage &message)
00039 {
00040         // Write the message and its type to the buffer
00041         defaultBuffer.reset();
00042         if (!message.writeTypeMessage(defaultBuffer))
00043         {
00044                 Logger::log( "ERROR: ComsMessageSender - Failed to write message type");
00045                 return false;
00046         }
00047         if (!message.writeMessage(defaultBuffer))
00048         {
00049                 Logger::log( "ERROR: ComsMessageSender - Failed to write message");
00050                 return false;
00051         }
00052 
00053         // Compress the message
00054         defaultBuffer.compressBuffer();
00055 
00056         return true;
00057 }
00058 
00059 #ifndef S3D_SERVER
00060 bool ComsMessageSender::sendToServer(
00061         ComsMessage &message, unsigned int flags)
00062 {
00063         if (!ScorchedClient::instance()->getNetInterfaceValid() ||
00064                 !ScorchedClient::instance()->getNetInterface().started()) return false;
00065         if (!formMessage(message)) return false;
00066 
00067         if (ScorchedClient::instance()->getComsMessageHandler().getMessageLogging())
00068         {
00069                 Logger::log(S3D::formatStringBuffer("Client::send(%s, %u)", 
00070                         message.getMessageType(),
00071                         defaultBuffer.getBufferUsed()));
00072         }       
00073         ScorchedClient::instance()->getNetInterface().sendMessageServer(
00074                 defaultBuffer, flags);
00075         return true;
00076 }
00077 #endif
00078 
00079 bool ComsMessageSender::sendToMultipleClients(
00080         ComsMessage &message, std::list<unsigned int> sendDestinations, unsigned int flags)
00081 {
00082         if (sendDestinations.empty()) return true;
00083         if (!formMessage(message)) return false;
00084 
00085         // Used to ensure we only send messages to each
00086         // destination once
00087         std::set<unsigned int> destinations;
00088         std::set<unsigned int>::iterator findItor;
00089         destinations.insert(0); // Make sure we don't send to dest 0
00090 
00091         std::list<unsigned int>::iterator itor;
00092         for (itor = sendDestinations.begin();
00093                 itor != sendDestinations.end();
00094                 itor++)
00095         {
00096                 unsigned int destination = *itor;
00097                 findItor = destinations.find(destination);
00098 
00099                 if (findItor == destinations.end())
00100                 {
00101                         destinations.insert(destination);
00102 
00103                         if (ScorchedServer::instance()->getComsMessageHandler().getMessageLogging())
00104                         {
00105                                 Logger::log(S3D::formatStringBuffer("Server::send(%s, %u, %u)", 
00106                                         message.getMessageType(),
00107                                         destination,
00108                                         defaultBuffer.getBufferUsed()));
00109                         }       
00110                         if (!ScorchedServer::instance()->getNetInterfaceValid() ||
00111                                 !ScorchedServer::instance()->getNetInterface().started())
00112                         {
00113                                 Logger::log( "ERROR: ComsMessageSender::sendToMultipleClients - Server not started");
00114                                 return false;
00115                         }
00116                         ScorchedServer::instance()->getNetInterface().sendMessageDest(
00117                                 defaultBuffer, destination, flags);
00118                 }
00119         }
00120 
00121         return true;
00122 }
00123 
00124 bool ComsMessageSender::sendToSingleClient(ComsMessage &message,
00125         unsigned int destination, unsigned int flags)
00126 {
00127         if (destination == 0) return true;
00128 
00129         std::list<unsigned int> destinations;
00130         destinations.push_back(destination);
00131         return sendToMultipleClients(message, destinations, flags);
00132 }
00133 
00134 bool ComsMessageSender::sendToAllConnectedClients(
00135         ComsMessage &message, unsigned int flags)
00136 {
00137         std::list<unsigned int> destinations;
00138         std::map<unsigned int, Tank *>::iterator itor;
00139         std::map<unsigned int, Tank *> tanks = 
00140                 ScorchedServer::instance()->getTankContainer().getPlayingTanks();
00141         for (itor = tanks.begin();
00142                 itor != tanks.end();
00143                 itor++)
00144         {
00145                 Tank *tank = (*itor).second;
00146                 destinations.push_back(tank->getDestinationId());
00147         }
00148         return sendToMultipleClients(message, destinations, flags);
00149 }
00150 
00151 bool ComsMessageSender::sendToAllPlayingClients(
00152         ComsMessage &message, unsigned int flags)
00153 {
00154         std::list<unsigned int> destinations;
00155         std::map<unsigned int, Tank *>::iterator itor;
00156         std::map<unsigned int, Tank *> tanks = 
00157                 ScorchedServer::instance()->getTankContainer().getPlayingTanks();
00158         for (itor = tanks.begin();
00159                 itor != tanks.end();
00160                 itor++)
00161         {
00162                 Tank *tank = (*itor).second;
00163                 if (tank->getState().getState() != TankState::sPending &&
00164                         tank->getState().getState() != TankState::sLoading &&
00165                         tank->getState().getState() != TankState::sInitializing)
00166                 {
00167                         destinations.push_back(tank->getDestinationId());
00168                 }
00169         }
00170         return sendToMultipleClients(message, destinations, flags);
00171 }

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