ServerChannelManager.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 <server/ServerChannelManager.h>
00022 #include <server/ScorchedServer.h>
00023 #include <server/ScorchedServerUtil.h>
00024 #include <server/ServerCommon.h>
00025 #include <lua/LUAScriptHook.h>
00026 #include <coms/ComsMessageSender.h>
00027 #include <coms/ComsChannelMessage.h>
00028 #include <coms/ComsChannelTextMessage.h>
00029 #include <common/OptionsScorched.h>
00030 #include <tank/TankContainer.h>
00031 #include <tank/TankState.h>
00032 #include <lang/LangResource.h>
00033 
00034 ServerChannelManager::ChannelEntry::ChannelEntry(
00035         ChannelDefinition def,
00036         ServerChannelFilter *filter,
00037         ServerChannelAuth *auth) :
00038         channelDef_(def),
00039         filter_(filter),
00040         auth_(auth)
00041 {
00042         ScorchedServer::instance()->getLUAScriptHook().addHookProvider("server_channeltext");
00043 }
00044 
00045 ServerChannelManager::ChannelEntry::~ChannelEntry()
00046 {
00047 }
00048 
00049 ServerChannelManager::DestinationLocalEntry::DestinationLocalEntry(
00050         unsigned int localId) :
00051         localId_(localId)
00052 {
00053 }
00054 
00055 ServerChannelManager::DestinationEntry::DestinationEntry(
00056         unsigned int destinationId) :
00057         destinationId_(destinationId),
00058         messageCount_(0), muteTime_(0)
00059 {
00060 }
00061 
00062 bool ServerChannelManager::DestinationEntry::hasChannel(const std::string &channel) 
00063 { 
00064         return (channels_.find(channel) != channels_.end()); 
00065 }
00066 
00067 void ServerChannelManager::DestinationEntry::addChannel(const std::string &channel, unsigned int localId, bool current)
00068 {
00069         if (!hasLocalId(localId)) return;
00070 
00071         if (current)
00072         {
00073                 localEntries_[localId].getChannels().insert(channel);
00074                 localEntries_[localId].getAvailableChannels().erase(channel);
00075         }
00076         else
00077         {
00078                 localEntries_[localId].getChannels().erase(channel);
00079                 localEntries_[localId].getAvailableChannels().insert(channel);
00080         }
00081 
00082         updateChannels();
00083 }
00084 
00085 void ServerChannelManager::DestinationEntry::removeChannel(const std::string &channel, unsigned int localId)
00086 {
00087         if (!hasLocalId(localId)) return;
00088         localEntries_[localId].getChannels().erase(channel);
00089         localEntries_[localId].getAvailableChannels().erase(channel);
00090         updateChannels();
00091 }
00092 
00093 void ServerChannelManager::DestinationEntry::getLocalIds(const std::string &channel, std::list<unsigned int> &ids)
00094 {
00095         std::map<unsigned int, DestinationLocalEntry>::iterator itor;
00096         for (itor = localEntries_.begin();
00097                 itor != localEntries_.end();
00098                 itor++)
00099         {
00100                 DestinationLocalEntry &entry = (*itor).second;
00101                 if (entry.getChannels().find(channel) != entry.getChannels().end())
00102                 {
00103                         ids.push_back((*itor).first);
00104                 }
00105         }
00106 }
00107 
00108 bool ServerChannelManager::DestinationEntry::hasLocalId(unsigned int localId)
00109 {
00110         return (localEntries_.find(localId) != localEntries_.end());
00111 }
00112 
00113 void ServerChannelManager::DestinationEntry::addLocalId(unsigned int localId)
00114 {
00115         if (hasLocalId(localId)) return;
00116         localEntries_[localId] = DestinationLocalEntry(localId);
00117         updateChannels();
00118 }
00119 
00120 void ServerChannelManager::DestinationEntry::removeLocalId(unsigned int localId)
00121 {
00122         if (!hasLocalId(localId)) return;
00123         localEntries_.erase(localId);
00124         updateChannels();
00125 }
00126 
00127 void ServerChannelManager::DestinationEntry::updateChannels()
00128 {
00129         channels_.clear();
00130         std::map<unsigned int, DestinationLocalEntry>::iterator itor;
00131         for (itor = localEntries_.begin();
00132                 itor != localEntries_.end();
00133                 itor++)
00134         {
00135                 DestinationLocalEntry &entry = (*itor).second;
00136                 channels_.insert(entry.getChannels().begin(), entry.getChannels().end());
00137         }
00138 }
00139 
00140 ServerChannelManager *ServerChannelManager::instance_ = 0;
00141 
00142 ServerChannelManager *ServerChannelManager::instance()
00143 {
00144         if (!instance_)
00145         {
00146                 instance_ = new ServerChannelManager;
00147         }
00148         return instance_;
00149 }
00150 
00151 ServerChannelManager::ServerChannelManager() :
00152         totalTime_(0.0f), lastMessageId_(0)
00153 {
00154         // Register to recieve comms messages
00155         ScorchedServer::instance()->getComsMessageHandler().addHandler(
00156                 "ComsChannelMessage",
00157                 this);
00158         ScorchedServer::instance()->getComsMessageHandler().addHandler(
00159                 "ComsChannelTextMessage",
00160                 this);
00161 
00162         // Create some default channels
00163         channelEntries_.push_back(new ChannelEntry(
00164                 ChannelDefinition("announce", ChannelDefinition::eReadOnlyChannel)));
00165         channelEntries_.push_back(new ChannelEntry(
00166                 ChannelDefinition("info", ChannelDefinition::eReadOnlyChannel)));
00167         channelEntries_.push_back(new ChannelEntry(
00168                 ChannelDefinition("general")));
00169         channelEntries_.push_back(new ChannelEntry(
00170                 ChannelDefinition("team"), 
00171                 new ServerChannelFilterTeams()));
00172         channelEntries_.push_back(new ChannelEntry(
00173                 ChannelDefinition("spam")));
00174         channelEntries_.push_back(new ChannelEntry(
00175                 ChannelDefinition("combat", ChannelDefinition::eReadOnlyChannel)));
00176         channelEntries_.push_back(new ChannelEntry(
00177                 ChannelDefinition("banner", ChannelDefinition::eReadOnlyChannel)));
00178         channelEntries_.push_back(new ChannelEntry(
00179                 ChannelDefinition("admin"),
00180                 0, 
00181                 new ServerChannelAuthAdmin()));
00182         channelEntries_.push_back(new ChannelEntry(
00183                 ChannelDefinition("whisper", ChannelDefinition::eWhisperChannel)));
00184 }
00185 
00186 ServerChannelManager::~ServerChannelManager()
00187 {
00188 }
00189 
00190 void ServerChannelManager::simulate(float frameTime)
00191 {
00192         const int MuteTime = 60;
00193         const int MuteThreshold = 10;
00194 
00195         totalTime_ += frameTime;
00196         if (totalTime_ > 10.0f)
00197         {
00198                 totalTime_ = 0.0f;
00199 
00200                 // Check each destination for the amount of messages they have
00201                 // sent recently
00202                 // If its more than a certain threshold, mute them for x seconds
00203                 std::map<unsigned int, DestinationEntry *>::iterator itor;
00204                 for (itor = destinationEntries_.begin();
00205                         itor != destinationEntries_.end();
00206                         itor++)
00207                 {
00208                         DestinationEntry *entry = itor->second;
00209                         if (entry->getMessageCount() > MuteThreshold)
00210                         {
00211                                 time_t t = time(0);
00212                                 entry->setMuteTime(t);
00213 
00214                                 ChannelText text("info", 
00215                                         LANG_RESOURCE_1("CHANNEL_AUTO_MUTED", 
00216                                         "You have been muted for {0} seconds for spamming!",
00217                                         MuteTime));
00218                                 sendText(text, entry->getDestinationId(), true);
00219                         }
00220                         else if (entry->getMuteTime())
00221                         {
00222                                 time_t t = time(0);
00223                                 if (t - entry->getMuteTime() > MuteTime)
00224                                 {
00225                                         entry->setMuteTime(0);
00226 
00227                                         ChannelText text("info", 
00228                                                 LANG_RESOURCE("CHANNEL_AUTO_UNMUTED", 
00229                                                 "You have been unmuted."));
00230                                         sendText(text, entry->getDestinationId(), true);
00231                                 }
00232                         }
00233                         entry->setMessageCount(0);
00234                 }
00235         }
00236 }
00237 
00238 void ServerChannelManager::destinationDisconnected(unsigned int destinationId)
00239 {
00240         DestinationEntry *entry = getDestinationEntryById(destinationId);
00241         if (!entry) return;
00242 
00243         destinationEntries_.erase(destinationId);
00244         delete entry;
00245 }
00246 
00247 ServerChannelManager::ChannelEntry *ServerChannelManager::getChannelEntryByName(const std::string &name)
00248 {
00249         std::list<ChannelEntry *>::iterator itor;
00250         for (itor = channelEntries_.begin();
00251                 itor != channelEntries_.end();
00252                 itor++)
00253         {
00254                 ChannelEntry *entry = *itor;
00255                 if (name == entry->getName()) return entry;
00256         }
00257         return 0;
00258 }
00259 
00260 ServerChannelManager::DestinationEntry *ServerChannelManager::getDestinationEntryById(
00261         unsigned int destinationId)
00262 {
00263         std::map<unsigned int, DestinationEntry *>::iterator findItor = 
00264                 destinationEntries_.find(destinationId);
00265         if (findItor == destinationEntries_.end()) return 0;
00266 
00267         return (*findItor).second;
00268 }
00269 
00270 std::list<std::string> ServerChannelManager::getAllChannels()
00271 {
00272         std::list<std::string> result;
00273         std::list<ChannelEntry *>::iterator itor;
00274         for (itor = channelEntries_.begin();
00275                 itor != channelEntries_.end();
00276                 itor++)
00277         {
00278                 ChannelEntry *channelEntry = (*itor);
00279                 result.push_back(channelEntry->getName());
00280         }
00281         return result;
00282 }
00283 
00284 void ServerChannelManager::registerClient(unsigned int destinationId, unsigned int localId,
00285         std::list<ChannelDefinition> &startChannels)
00286 {
00287         // Get the sender for this message
00288         DestinationEntry *destEntry = getDestinationEntryById(destinationId);
00289         if (destEntry && destEntry->hasLocalId(localId)) return; // Already an entry
00290 
00291         // Add the new entry
00292         if (!destEntry)
00293         {
00294                 destEntry = new DestinationEntry(destinationId);
00295                 destinationEntries_[destinationId] = destEntry;
00296         }
00297         // Add the new local entry
00298         if (!destEntry->hasLocalId(localId))
00299         {
00300                 destEntry->addLocalId(localId);
00301         }
00302 
00303         // Join the client to the new channels
00304         joinClient(destinationId, localId, startChannels);
00305 }
00306 
00307 void ServerChannelManager::deregisterClient(unsigned int destinationId, unsigned int localId)
00308 {
00309         // Get the sender for this message
00310         DestinationEntry *destEntry =  getDestinationEntryById(destinationId);
00311         if (!destEntry || !destEntry->hasLocalId(localId)) return; // No such user
00312 
00313         // Remove the entry
00314         destEntry->removeLocalId(localId);
00315 }
00316 
00317 void ServerChannelManager::refreshDestination(unsigned int destinationId)
00318 {
00319         // Get the sender for this message
00320         DestinationEntry *destEntry = getDestinationEntryById(destinationId);
00321 
00322         // Form the list of available and joined channels
00323         // for each local id and send them back to the client
00324         std::map<unsigned int, DestinationLocalEntry> &localEntries = 
00325                 destEntry->getLocalEntries();
00326         std::map<unsigned int, DestinationLocalEntry>::iterator localItor;
00327         for (localItor = localEntries.begin();
00328                 localItor != localEntries.end();
00329                 localItor++)
00330         {
00331                 unsigned int localId = localItor->first;
00332                 DestinationLocalEntry &localEntry = localItor->second;
00333 
00334                 ComsChannelMessage message(ComsChannelMessage::eJoinRequest, localId);
00335                 bool differentMessage = false;
00336                 std::list<ChannelEntry *>::iterator itor;
00337                 for (itor = channelEntries_.begin();
00338                         itor != channelEntries_.end();
00339                         itor++)
00340                 {
00341                         ChannelEntry *channelEntry = (*itor);
00342 
00343                         // Check if a user is allowed a channel at all
00344                         bool allowedChannel = (!channelEntry->getAuth() ||
00345                                 channelEntry->getAuth()->allowConnection(
00346                                 channelEntry->getName(), destinationId));
00347 
00348                         // Check if they currently have the channel
00349                         if (localEntry.getChannels().find(channelEntry->getName()) !=
00350                                 localEntry.getChannels().end())
00351                         {
00352                                 // They currently have the channel in their 
00353                                 // current subscription list
00354                                 if (allowedChannel)
00355                                 {
00356                                         // They are allowed this channel
00357                                         // Add it to the list of subscribed channels
00358                                         message.getChannels().push_back(
00359                                                 channelEntry->getDefinition());
00360                                 }
00361                                 else
00362                                 {
00363                                         // They are not allowed this channel
00364                                         // Remove it from their list
00365                                         destEntry->removeChannel(channelEntry->getName(), localId);
00366                                         differentMessage = true;
00367                                 }
00368                         }
00369                         else if (localEntry.getAvailableChannels().find(channelEntry->getName()) !=
00370                                 localEntry.getAvailableChannels().end())
00371                         {
00372                                 // They currently have their channel in their
00373                                 // avialable channel list
00374                                 if (allowedChannel)
00375                                 {
00376                                         // They are allowed this channel
00377                                         // Add it to the list of available channels
00378                                         message.getAvailableChannels().push_back(
00379                                                 channelEntry->getDefinition());
00380                                 }
00381                                 else
00382                                 {
00383                                         // They are not allowed this channel
00384                                         // Remove it from their list
00385                                         destEntry->removeChannel(channelEntry->getName(), localId);
00386                                         differentMessage = true;
00387                                 }
00388                         }
00389                         else
00390                         {
00391                                 // This a new channel the user has not seen
00392                                 if (allowedChannel)
00393                                 {
00394                                         // They are allowed this channel
00395                                         // Add it to the list of available channels
00396                                         message.getAvailableChannels().push_back(
00397                                                 channelEntry->getDefinition());
00398                                         destEntry->addChannel(channelEntry->getName(), localId, false);
00399                                         differentMessage = true;
00400                                 }
00401                         }
00402                 }
00403 
00404                 if (differentMessage)
00405                 {
00406                         // The user's subscriptions have changed
00407                         // Send the new subscriptions
00408                         ComsMessageSender::sendToSingleClient(message, destinationId);
00409                 }
00410         }
00411 }
00412 
00413 void ServerChannelManager::joinClient(unsigned int destinationId, unsigned int localId,
00414         std::list<ChannelDefinition> &startChannels)
00415 {
00416         // Get the sender for this message
00417         DestinationEntry *destEntry = getDestinationEntryById(destinationId);
00418         if (!destEntry || !destEntry->hasLocalId(localId)) return; // No such user
00419 
00420         // Form the list of available and joined channels
00421         // and send them back to the client
00422         ComsChannelMessage message(ComsChannelMessage::eJoinRequest, localId);
00423         std::list<ChannelEntry *>::iterator itor;
00424         for (itor = channelEntries_.begin();
00425                 itor != channelEntries_.end();
00426                 itor++)
00427         {
00428                 ChannelEntry *channelEntry = (*itor);
00429 
00430                 // Check if a user is allowed a channel at all
00431                 if (channelEntry->getAuth() &&
00432                         !channelEntry->getAuth()->allowConnection(
00433                         channelEntry->getName(), destinationId))
00434                 {
00435                         destEntry->removeChannel(channelEntry->getName(), localId);
00436                         continue;
00437                 }
00438 
00439                 // Check if the user has asked for this channel
00440                 bool current = false;
00441                 std::list<ChannelDefinition>::iterator startItor;
00442                 for (startItor = startChannels.begin();
00443                         startItor != startChannels.end();
00444                         startItor++)
00445                 {
00446                         const char *startChannel = startItor->getChannel();
00447                         if (0 == strcmp(startChannel, channelEntry->getName()))
00448                         {
00449                                 current = true;
00450                                 break;
00451                         }
00452                 }
00453 
00454                 destEntry->addChannel(channelEntry->getName(), localId, current);
00455                 if (current) message.getChannels().push_back(channelEntry->getDefinition());
00456                 else message.getAvailableChannels().push_back(channelEntry->getDefinition());
00457         }
00458         ComsMessageSender::sendToSingleClient(message, destinationId);
00459 }
00460 
00461 void ServerChannelManager::sendText(const ChannelText &constText, 
00462         unsigned int destination, bool log, bool filter)
00463 {
00464         DestinationEntry *destinationEntry = getDestinationEntryById(
00465                 destination);
00466         if (destinationEntry)
00467         {
00468                 std::map<unsigned int, DestinationEntry *> destinations;
00469                 destinations[destination] = destinationEntry;
00470                 actualSend(constText, destinations, log, filter);
00471         }
00472 }
00473 
00474 void ServerChannelManager::sendText(const ChannelText &constText, bool log, bool filter)
00475 {
00476         actualSend(constText, destinationEntries_, log, filter);
00477 }
00478 
00479 void ServerChannelManager::actualSend(const ChannelText &constText,
00480         std::map<unsigned int, DestinationEntry *> &destinations, bool log, bool filter)
00481 {
00482         ChannelText text = constText;
00483 
00484         // Get the tank for this message (if any)
00485         Tank *tank = ScorchedServer::instance()->getTankContainer().getTankById(
00486                 text.getSrcPlayerId());
00487 
00488         // Check that this channel exists
00489         ChannelEntry *channelEntry = getChannelEntryByName(text.getChannel());
00490         if (!channelEntry)
00491         {
00492                 // This channel does not exist
00493                 return;
00494         }
00495 
00496         LangString filteredText(text.getMessage());
00497         if (filter)
00498         {
00499                 // Filter the string for bad language
00500                 ScorchedServerUtil::instance()->textFilter.filterString(filteredText);
00501 
00502                 // Remove any bad characters
00503                 for (unsigned int *r = (unsigned int *) filteredText.c_str(); *r; r++)
00504                 {
00505                         if (*r == '%' || *r < 0) *r = ' ';
00506                         else if (*r == '[') *r = '(';
00507                         else if (*r == ']') *r = ')';
00508                 }
00509                 if (!ScorchedServer::instance()->getOptionsGame().getAllowMultiLingualChat())
00510                 {
00511                         for (unsigned int *r = (unsigned int *) filteredText.c_str(); *r; r++)
00512                         {
00513                                 if (*r > 127) *r = '?';
00514                         }
00515                 }
00516         }
00517 
00518         // Update the server console with the say text
00519         std::string logtext;
00520         if (log)
00521         {
00522                 std::string logMessage = LangStringUtil::convertFromLang(filteredText);
00523                 if (tank)
00524                 {
00525                         logtext = S3D::formatStringBuffer("[%s][%s] : \"%s\"", 
00526                                 text.getChannel().c_str(),
00527                                 tank->getCStrName().c_str(),
00528                                 logMessage.c_str());
00529                 }
00530                 else if (text.getAdminPlayer()[0])
00531                 {
00532                         logtext = S3D::formatStringBuffer("[%s][%s (Admin)] : \"%s\"", 
00533                                 text.getChannel().c_str(),
00534                                 text.getAdminPlayer().c_str(),
00535                                 logMessage.c_str());
00536                 }
00537                 else
00538                 {
00539                         logtext = S3D::formatStringBuffer("[%s] : \"%s\"", 
00540                                 text.getChannel().c_str(),
00541                                 logMessage.c_str());
00542                 }
00543         }
00544         if (logtext[0])
00545         {
00546                 ServerCommon::serverLog(logtext);
00547                 MessageEntry messageEntry;
00548                 messageEntry.message = logtext;
00549                 messageEntry.messageid = ++lastMessageId_;
00550                 lastMessages_.push_back(messageEntry);
00551                 if (lastMessages_.size() > 25) lastMessages_.pop_front();
00552         }
00553 
00554         // Update the message with the filtered text
00555         text.setMessage(filteredText);
00556 
00557         // Send to any scripts for processing
00558         ScorchedServer::instance()->getLUAScriptHook().callHook("server_channeltext", 
00559                 fixed(true, tank?tank->getPlayerId():0),
00560                 text.getChannel(),
00561                 text.getMessage());
00562 
00563         // Send to all clients
00564         std::map<unsigned int, DestinationEntry *>::iterator destItor;
00565         for (destItor = destinations.begin();
00566                 destItor != destinations.end();
00567                 destItor++)
00568         {
00569                 DestinationEntry *entry = (*destItor).second;
00570                 if (!channelEntry->getFilter() || channelEntry->getFilter()->sentToDestination(
00571                         text, entry->getDestinationId()))
00572                 {
00573                         if (entry->hasChannel(text.getChannel()))
00574                         {
00575                                 ComsChannelTextMessage newTextMessage(text);
00576                                 entry->getLocalIds(text.getChannel(), newTextMessage.getIds());
00577                                 ComsMessageSender::sendToSingleClient(
00578                                         newTextMessage, entry->getDestinationId());
00579                         }
00580                 }
00581         }
00582 }
00583 
00584 bool ServerChannelManager::processMessage(
00585         NetMessage &netNessage,
00586         const char *messageType,
00587         NetBufferReader &reader)
00588 {
00589         // Check which message we have got
00590         if (0 == strcmp("ComsChannelMessage", messageType))
00591         {
00592                 // We have a ChannelMessage from the server
00593                 ComsChannelMessage channelMessage;
00594                 if (!channelMessage.readMessage(reader)) return false;
00595 
00596                 // Check which ChannelMessage was sent
00597                 switch (channelMessage.getType())
00598                 {
00599                 case ComsChannelMessage::eRegisterRequest:
00600                         registerClient(netNessage.getDestinationId(), channelMessage.getId(),
00601                                 channelMessage.getChannels());
00602                         break;
00603                 case ComsChannelMessage::eDeregisterRequest:
00604                         deregisterClient(netNessage.getDestinationId(), channelMessage.getId());
00605                         break;
00606                 case ComsChannelMessage::eJoinRequest:
00607                         joinClient(netNessage.getDestinationId(), channelMessage.getId(),
00608                                 channelMessage.getChannels());
00609                         break;
00610                 }
00611         }
00612         else if (0 == strcmp("ComsChannelTextMessage", messageType))
00613         {
00614                 // We have a ChannelTextMessage from the server
00615                 ComsChannelTextMessage textMessage;
00616                 if (!textMessage.readMessage(reader)) return false;
00617                 textMessage.getChannelText().setAdminPlayer("");
00618                 textMessage.getChannelText().setMessageKey("");
00619                 textMessage.getChannelText().setMessageValue("");
00620 
00621                 // Validate that this message came from this tank
00622                 Tank *tank = ScorchedServer::instance()->getTankContainer().getTankById(
00623                         textMessage.getChannelText().getSrcPlayerId());
00624                 if (!tank || tank->getDestinationId() != 
00625                         netNessage.getDestinationId()) return true;
00626 
00627                 // Check that this client has this channel
00628                 DestinationEntry *destEntry = 
00629                         getDestinationEntryById(netNessage.getDestinationId());
00630                 if (!destEntry || !destEntry->hasChannel(
00631                         textMessage.getChannelText().getChannel()))
00632                 {
00633                         // This client does not have this channel
00634                         return true;
00635                 }
00636 
00637                 // Check that this channel exists and is not a read only channel
00638                 ChannelEntry *channelEntry = getChannelEntryByName(
00639                         textMessage.getChannelText().getChannel());
00640                 if (!channelEntry)
00641                 {
00642                         // This channel does not exist
00643                         return true;
00644                 }
00645                 if (channelEntry->getDefinition().getType() & 
00646                         ChannelDefinition::eReadOnlyChannel)
00647                 {
00648                         // Cannot send to this channel from a client
00649                         return true;
00650                 }
00651                 if ((!(channelEntry->getDefinition().getType() &
00652                         ChannelDefinition::eWhisperChannel) &&
00653                         textMessage.getChannelText().getDestPlayerId()) ||
00654                         
00655                         ((channelEntry->getDefinition().getType() &
00656                         ChannelDefinition::eWhisperChannel) &&
00657                         !textMessage.getChannelText().getDestPlayerId()))
00658                 {
00659                         // Cannot send a whisper message to a non-whisper channel
00660                         // or
00661                         // Cannot send a non-whisper message to a whisper channel
00662                         return true;
00663                 }
00664                 if ((channelEntry->getDefinition().getType() &
00665                         ChannelDefinition::eWhisperChannel) &&
00666                         textMessage.getChannelText().getDestPlayerId() == 
00667                         textMessage.getChannelText().getSrcPlayerId())
00668                 {
00669                         // Cannot whisper to self
00670                         return true;
00671                 }
00672 
00673                 // Check that we don't recieve too much text
00674                 if (textMessage.getChannelText().getMessage().size() > 1024) return true;
00675 
00676                 // Increment message count
00677                 destEntry->setMessageCount(destEntry->getMessageCount() + 1);
00678 
00679                 // Check this tank has not been admin muted
00680                 // Check this tank has not been muted for spamming
00681                 if (tank->getState().getMuted() || 
00682                         destEntry->getMuteTime())
00683                 {
00684                         ChannelText mutedText(textMessage.getChannelText());
00685                         mutedText.setMessage(
00686                                 LANG_RESOURCE("SERVER_MUTED_MESSAGE", "**muted** ") + 
00687                                 mutedText.getMessage());
00688                         ChannelText adminText(mutedText);
00689                         adminText.setChannel("admin");
00690 
00691                         sendText(mutedText, tank->getDestinationId(), true);
00692                         sendText(adminText, false);
00693                         return true;
00694                 }
00695 
00696                 // Send the text
00697                 if (textMessage.getChannelText().getDestPlayerId())
00698                 {
00699                         // This is a whisper message, check the destination exists
00700                         Tank *destTank = ScorchedServer::instance()->getTankContainer().
00701                                 getTankById(textMessage.getChannelText().getDestPlayerId());
00702                         if (destTank && destTank->getDestinationId())
00703                         {
00704                                 // Send to this destination
00705                                 sendText(textMessage.getChannelText(), 
00706                                         destTank->getDestinationId(), true);
00707 
00708                                 // And the the sender (if different)
00709                                 if (tank->getDestinationId() !=
00710                                         destTank->getDestinationId())
00711                                 {
00712                                         sendText(textMessage.getChannelText(), 
00713                                                 tank->getDestinationId(), true);
00714                                 }
00715                         }
00716                 }
00717                 else
00718                 {
00719                         // Send to all destinations
00720                         sendText(textMessage.getChannelText(), true);
00721                 }
00722         }
00723         else return false;
00724 
00725         return true;
00726 }

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