00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
00086
00087 std::set<unsigned int> destinations;
00088 std::set<unsigned int>::iterator findItor;
00089 destinations.insert(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 }