00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00095 ChannelEntry *entry = new ChannelEntry(reciever);
00096 unsigned int channelId = ++nextRecieverId_;
00097 recievers_[channelId] = entry;
00098
00099
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
00120 delete recievers_[channelId];
00121 recievers_.erase(channelId);
00122
00123
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
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
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
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
00292 if (0 == strcmp("ComsChannelMessage", messageType))
00293 {
00294
00295 ComsChannelMessage channelMessage;
00296 if (!channelMessage.readMessage(reader)) return false;
00297
00298
00299 std::map<unsigned int, ChannelEntry *>::iterator findItor =
00300 recievers_.find(channelMessage.getId());
00301 if (findItor == recievers_.end()) return true;
00302 ChannelEntry *entry = (*findItor).second;
00303 ClientChannelManagerI *reciever = entry->getUser();
00304
00305
00306 if (channelMessage.getType() == ComsChannelMessage::eJoinRequest)
00307 {
00308
00309 entry->setChannels(channelMessage.getChannels());
00310 reciever->registeredForChannels(channelMessage.getChannels(),
00311 channelMessage.getAvailableChannels());
00312 }
00313 }
00314 else if (0 == strcmp("ComsChannelTextMessage", messageType))
00315 {
00316
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
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
00333 if (tank && tank->getState().getMuted()) return true;
00334
00335
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
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
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 }