ClientChannelManager.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 <client/ClientChannelManager.h>
00022 #include <client/ScorchedClient.h>
00023 #include <coms/ComsMessageSender.h>
00024 #include <coms/ComsChannelMessage.h>
00025 #include <coms/ComsChannelTextMessage.h>
00026 #include <console/ConsoleRuleMethodIAdapter.h>
00027 #include <common/Logger.h>
00028 #include <tank/TankContainer.h>
00029 #include <tank/TankState.h>
00030 #include <tank/TankPosition.h>
00031 #include <sprites/TalkRenderer.h>
00032 #include <engine/ActionController.h>
00033 
00034 ClientChannelManager::ChannelEntry::ChannelEntry(ClientChannelManagerI *user) :
00035         user_(user)
00036 {
00037 }
00038 
00039 void ClientChannelManager::ChannelEntry::setChannels(std::list<ChannelDefinition> &channels)
00040 {
00041         channels_.clear();
00042         std::list<ChannelDefinition>::iterator itor;
00043         for (itor = channels.begin();
00044                 itor != channels.end();
00045                 itor++)
00046         {
00047                 channels_.insert(itor->getChannel());
00048         }
00049 }
00050 
00051 bool ClientChannelManager::ChannelEntry::hasChannel(const std::string &channel)
00052 {
00053         return (channels_.find(channel) != channels_.end());
00054 }
00055 
00056 unsigned int ClientChannelManager::nextRecieverId_ = 0;
00057 
00058 ClientChannelManager *ClientChannelManager::instance_ = 0;
00059 
00060 ClientChannelManager *ClientChannelManager::instance()
00061 {
00062         if (!instance_)
00063         {
00064                 instance_ = new ClientChannelManager;
00065         }
00066         return instance_;
00067 }
00068 
00069 ClientChannelManager::ClientChannelManager()
00070 {
00071         ScorchedClient::instance()->getComsMessageHandler().addHandler(
00072                 "ComsChannelMessage",
00073                 this);
00074         ScorchedClient::instance()->getComsMessageHandler().addHandler(
00075                 "ComsChannelTextMessage",
00076                 this);
00077 
00078         new ConsoleRuleMethodIAdapterEx<ClientChannelManager>(
00079                 this, &ClientChannelManager::say, "Say", 
00080                 ConsoleUtil::formParams(
00081                 ConsoleRuleParam("channel", ConsoleRuleTypeString),
00082                 ConsoleRuleParam("text", ConsoleRuleTypeString)));
00083 }
00084 
00085 ClientChannelManager::~ClientChannelManager()
00086 {
00087 }
00088 
00089 bool ClientChannelManager::registerClient(ClientChannelManagerI *reciever,
00090         std::list<std::string> &channels)
00091 {
00092         if (getChannelEntry(reciever) > 0) return false;
00093 
00094         // Add a new reciever
00095         ChannelEntry *entry = new ChannelEntry(reciever);
00096         unsigned int channelId = ++nextRecieverId_;
00097         recievers_[channelId] = entry;
00098 
00099         // Send the request for a new reciever
00100         ComsChannelMessage message(ComsChannelMessage::eRegisterRequest, channelId);
00101         std::list<std::string>::iterator itor;
00102         for (itor = channels.begin();
00103                 itor != channels.end();
00104                 itor++)
00105         {
00106                 ChannelDefinition entry(itor->c_str());
00107                 message.getChannels().push_back(entry);
00108         }
00109         ComsMessageSender::sendToServer(message);
00110 
00111         return true;
00112 }
00113 
00114 bool ClientChannelManager::deregisterClient(ClientChannelManagerI *reciever)
00115 {
00116         unsigned int channelId = getChannelEntry(reciever);
00117         if (channelId == 0) return false;
00118 
00119         // Remove the reciever
00120         delete recievers_[channelId];
00121         recievers_.erase(channelId);
00122 
00123         // Send the request to remove the reciever
00124         ComsChannelMessage message(ComsChannelMessage::eDeregisterRequest, channelId);
00125         ComsMessageSender::sendToServer(message);
00126 
00127         return true;
00128 }
00129 
00130 bool ClientChannelManager::changeRegistration(ClientChannelManagerI *reciever,
00131         std::list<std::string> &channels)
00132 {
00133         unsigned int channelId = getChannelEntry(reciever);
00134         if (channelId == 0) return false;
00135 
00136         // Send the request to add a new channel
00137         ComsChannelMessage message(ComsChannelMessage::eJoinRequest, channelId);        
00138         std::list<std::string>::iterator itor;
00139         for (itor = channels.begin();
00140                 itor != channels.end();
00141                 itor++)
00142         {
00143                 ChannelDefinition entry(itor->c_str());
00144                 message.getChannels().push_back(entry);
00145         }
00146         ComsMessageSender::sendToServer(message);
00147 
00148         return true;
00149 }
00150 
00151 void ClientChannelManager::addChannel(const char *lookfor, const char *channel)
00152 {
00153         std::map<unsigned int, ChannelEntry *>::iterator itor;
00154         for (itor = recievers_.begin();
00155                 itor != recievers_.end();
00156                 itor++)
00157         {
00158                 ChannelEntry *r = (*itor).second;
00159                 if (r->hasChannel(lookfor))
00160                 {
00161                         std::set<std::string> currentChannels = r->getChannels();
00162                         currentChannels.insert(channel);
00163                         std::list<std::string> channels;
00164                         std::set<std::string>::iterator itor;
00165                         for (itor = currentChannels.begin();
00166                                 itor != currentChannels.end();
00167                                 itor++)
00168                         {
00169                                 channels.push_back(*itor);
00170                         }
00171 
00172                         changeRegistration(r->getUser(), channels);
00173                         break;
00174                 }
00175         }
00176 }
00177 
00178 void ClientChannelManager::removeChannel(const char *channel)
00179 {
00180         std::map<unsigned int, ChannelEntry *>::iterator itor;
00181         for (itor = recievers_.begin();
00182                 itor != recievers_.end();
00183                 itor++)
00184         {
00185                 ChannelEntry *r = (*itor).second;
00186                 if (r->hasChannel(channel))
00187                 {
00188                         std::set<std::string> currentChannels = r->getChannels();
00189                         currentChannels.erase(channel);
00190                         std::list<std::string> channels;
00191                         std::set<std::string>::iterator itor;
00192                         for (itor = currentChannels.begin();
00193                                 itor != currentChannels.end();
00194                                 itor++)
00195                         {
00196                                 channels.push_back(*itor);
00197                         }
00198 
00199                         changeRegistration(r->getUser(), channels);
00200                         break;
00201                 }
00202         }
00203 }
00204 
00205 unsigned int ClientChannelManager::getChannelEntry(ClientChannelManagerI *reciever)
00206 {
00207         std::map<unsigned int, ChannelEntry *>::iterator itor;
00208         for (itor = recievers_.begin();
00209                 itor != recievers_.end();
00210                 itor++)
00211         {
00212                 ChannelEntry *r = (*itor).second;
00213                 if (r->getUser() == reciever) return (*itor).first;
00214         }
00215         return 0;
00216 }
00217 
00218 void ClientChannelManager::say(std::vector<ConsoleRuleValue> &values)
00219 {
00220         ConsoleRuleValue &channelValue = values[1];
00221         ConsoleRuleValue &textValue = values[2];
00222 
00223         ChannelText message(channelValue.valueString.c_str(), 
00224                 LANG_STRING(textValue.valueString));
00225         sendText(message);
00226 }
00227 
00228 void ClientChannelManager::sendText(const ChannelText &constText)
00229 {
00230         ChannelText text = constText;
00231 
00232         unsigned int playerId = 
00233                 ScorchedClient::instance()->getTankContainer().getCurrentPlayerId();
00234         if (!playerId)
00235         {
00236                 std::map<unsigned int, Tank *> &tanks = 
00237                         ScorchedClient::instance()->getTankContainer().getPlayingTanks();
00238                 std::map<unsigned int, Tank *>::iterator itor;
00239                 for (itor = tanks.begin();
00240                         itor != tanks.end();
00241                         itor++)
00242                 {
00243                         Tank *tank = (*itor).second;
00244                         if (tank->getDestinationId() == 
00245                                 ScorchedClient::instance()->getTankContainer().getCurrentDestinationId())
00246                         {
00247                                 playerId = tank->getPlayerId();
00248                                 break;
00249                         }
00250                 }
00251         }
00252 
00253         text.setSrcPlayerId(playerId);
00254         ComsChannelTextMessage message(text);
00255         ComsMessageSender::sendToServer(message);
00256 }
00257 
00258 void ClientChannelManager::showText(const ChannelText &constText)
00259 {
00260         ChannelText text = constText;
00261 
00262         // Add this line to the console
00263         if (!(text.getFlags() & ChannelText::eNoLog))
00264         {
00265                 std::string mes(LangStringUtil::convertFromLang(text.getMessage()));
00266 
00267                 Logger::log(S3D::formatStringBuffer("[%s] : %s",
00268                         text.getChannel().c_str(),
00269                         mes.c_str()));
00270         }
00271 
00272         // Send to all recievers
00273         std::map<unsigned int, ChannelEntry *>::iterator itor;
00274         for (itor = recievers_.begin();
00275                 itor != recievers_.end();
00276                 itor++)
00277         {
00278                 ChannelEntry *entry = (*itor).second;
00279                 if (entry->hasChannel(text.getChannel()))
00280                 {
00281                         entry->getUser()->channelText(text);
00282                 }
00283         }
00284 }
00285 
00286 bool ClientChannelManager::processMessage(
00287         NetMessage &netNessage,
00288         const char *messageType,
00289         NetBufferReader &reader)
00290 {
00291         // Check which message we have got
00292         if (0 == strcmp("ComsChannelMessage", messageType))
00293         {
00294                 // We have a ChannelMessage from the server
00295                 ComsChannelMessage channelMessage;
00296                 if (!channelMessage.readMessage(reader)) return false;
00297 
00298                 // Get the reciever for this message
00299                 std::map<unsigned int, ChannelEntry *>::iterator findItor =
00300                         recievers_.find(channelMessage.getId());
00301                 if (findItor == recievers_.end()) return true; // No reciever
00302                 ChannelEntry *entry = (*findItor).second;
00303                 ClientChannelManagerI *reciever = entry->getUser();
00304 
00305                 // Check which ChannelMessage was sent
00306                 if (channelMessage.getType() == ComsChannelMessage::eJoinRequest)
00307                 {
00308                         // Its a channels request
00309                         entry->setChannels(channelMessage.getChannels());
00310                         reciever->registeredForChannels(channelMessage.getChannels(),
00311                                 channelMessage.getAvailableChannels());
00312                 }
00313         }
00314         else if (0 == strcmp("ComsChannelTextMessage", messageType))
00315         {
00316                 // We have a ChannelTextMessage from the server
00317                 ComsChannelTextMessage textMessage;
00318                 if (!textMessage.readMessage(reader)) return false;
00319 
00320                 Tank *tank = ScorchedClient::instance()->getTankContainer().getTankById(
00321                         textMessage.getChannelText().getSrcPlayerId());
00322                 if(tank && tank->getState().getState() == TankState::sNormal)
00323                 {
00324                         // put a speach bubble over the talking tank
00325                         Vector white(1.0f, 1.0f, 1.0f);
00326                         TalkRenderer *talk = new TalkRenderer(
00327                                 tank->getPosition().getTankTurretPosition().asVector(),
00328                                 white);
00329                         ScorchedClient::instance()->getActionController().
00330                                 addAction(new SpriteAction(talk));
00331                 }
00332                 // Ignore any messages from this tank
00333                 if (tank && tank->getState().getMuted()) return true;
00334 
00335                 // Log this message
00336                 std::string mes(LangStringUtil::convertFromLang(
00337                         textMessage.getChannelText().getMessage()));
00338                 if (tank)
00339                 {
00340                         Logger::log(S3D::formatStringBuffer("[%s][%s] : %s",
00341                                 textMessage.getChannelText().getChannel().c_str(),
00342                                 tank->getCStrName().c_str(),
00343                                 mes.c_str()));
00344                 }
00345                 else
00346                 {
00347                         Logger::log(S3D::formatStringBuffer("[%s] : %s",
00348                                 textMessage.getChannelText().getChannel().c_str(),
00349                                 mes.c_str()));
00350                 }
00351 
00352                 // Foreach reciever
00353                 std::list<unsigned int>::iterator itor;
00354                 for (itor = textMessage.getIds().begin();
00355                         itor != textMessage.getIds().end();
00356                         itor++)
00357                 {
00358                         unsigned int id = (*itor);
00359 
00360                         // Get the reciever for this message
00361                         std::map<unsigned int, ChannelEntry *>::iterator findItor =
00362                                 recievers_.find(id);
00363                         if (findItor != recievers_.end())
00364                         {
00365                                 ClientChannelManagerI *reciever = (*findItor).second->getUser();
00366                                 reciever->channelText(textMessage.getChannelText());
00367                         }
00368                 }
00369         }
00370         else return false;
00371 
00372         return true;
00373 }

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