Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / net / module_local_gateway.cpp
blob0782c2d2cde1caa2667bc7270e2b5f1b7083a958
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "stdnet.h"
18 #include "nel/net/module_gateway.h"
19 #include "nel/net/module.h"
20 #include "nel/net/module_manager.h"
21 #include "nel/net/module_socket.h"
22 #include "nel/net/module_message.h"
24 using namespace std;
25 using namespace NLMISC;
29 namespace NLNET
33 /** A simple gateway that interconnect module locally
34 * For testing purpose and simple case.
36 class CLocalGateway :
37 public CModuleBase,
38 public CModuleGateway,
39 public CModuleSocket
41 // the proxy that represent this gateway
42 // TModuleGatewayProxyPtr _ThisProxy;
44 typedef CTwinMap<TModuleProxyPtr, TStringId> TModuleProxies;
45 // The modules proxies
46 TModuleProxies _ModuleProxies;
49 public:
51 CLocalGateway()
56 ~CLocalGateway()
58 // we need to unplug any plugged module
59 while (!_PluggedModules.getAToBMap().empty())
61 _PluggedModules.getAToBMap().begin()->second->unplugModule(this);
64 // must be done before the other destructors are called
65 unregisterSocket();
66 unregisterGateway();
69 /***********************************************************
70 ** Gateway methods
71 ***********************************************************/
72 virtual const std::string &getGatewayName() const
74 return getModuleName();
76 virtual const std::string &getFullyQualifiedGatewayName() const
78 return getModuleFullyQualifiedName();
80 /// Return the gateway proxy of this gateway
81 // virtual TModuleGatewayProxyPtr &getGatewayProxy()
82 // {
83 // nlassert(!_ThisProxy.isNull());
84 // return _ThisProxy;
85 // }
87 /// Create and bind to this gateway a new transport
88 virtual void createTransport(const std::string &/* transportClass */, const std::string &/* instanceName */)
91 /// Delete a transport (this will close any open route)
92 virtual void deleteTransport(const std::string &/* instanceName */)
96 /// Activate/stop peer invisible mode on a transport
97 virtual void setTransportPeerInvisible(const std::string &/* transportInstanceName */, bool /* peerInvisible */)
99 // unsupported
100 nlstop;
103 /// Activate/stop firewalling mode on a transport
104 virtual void setTransportFirewallMode(const std::string &/* transportInstanceName */, bool /* firewalled */)
106 // unsupported
107 nlstop;
110 /// Send a command to a transport
111 virtual void transportCommand(const TParsedCommandLine &/* commandLine */)
114 virtual IGatewayTransport *getGatewayTransport(const std::string &/* transportName */) const
116 // there are no transport here
117 return NULL;
120 virtual uint32 getTransportCount() const
122 return 0;
125 virtual uint32 getRouteCount() const
127 return 0;
130 virtual uint32 getReceivedPingCount() const
132 return 0;
135 virtual void onRouteAdded(CGatewayRoute * /* route */)
139 /// A route is removed by a transport
140 virtual void onRouteRemoved(CGatewayRoute * /* route */)
144 /// A transport have received a message
145 virtual void onReceiveMessage(CGatewayRoute * /* from */, const CMessage &/* msgin */)
149 virtual void createSecurityPlugin(const std::string &/* className */)
152 virtual void sendSecurityCommand(const TParsedCommandLine &/* command */)
155 virtual void removeSecurityPlugin()
160 // virtual bool isGatewayServerOpen()
161 // {
162 // return false;
163 // }
165 // virtual CInetAddress getGatewayServerAddress()
166 // {
167 // CInetAddress invalid;
169 // return invalid;
170 // }
171 // virtual void getGatewayClientList(std::vector<TModuleGatewayProxyPtr> gatewayList)
172 // {
173 // return;
174 // }
175 // virtual void openGatewayServer(uint16 listeningPort)
176 // {
177 // nlstop;
178 // }
179 // virtual void closeGatewayServer()
180 // {
181 // nlstop;
182 // }
183 // virtual void shutdownGatewayServer()
184 // {
185 // nlstop;
186 // }
187 // virtual void onGatewayServerOpen()
188 // {
189 // }
190 // virtual void onGatewayServerClose()
191 // {
192 // }
193 // virtual TModuleGatewayConstant onClientGatewayConnect(TModuleGatewayProxyPtr &clientGateway)
194 // {
195 // return mgc_reject_connection;
196 // }
197 // virtual void onClientGatewayDisconnect(TModuleGatewayProxyPtr &clientGateway)
198 // {
199 // }
200 // virtual void getGatewayServerList(std::vector<TModuleGatewayProxyPtr> serverList)
201 // {
202 // return;
203 // }
204 // virtual bool isGatewayConnected()
205 // {
206 // return false;
207 // }
208 // virtual void connectGateway(CInetAddress serverAddress)
209 // {
210 // nlstop;
211 // }
212 // virtual void disconnectGateway(TModuleGatewayProxyPtr &serverGateway)
213 // {
214 // nlstop;
215 // }
216 // virtual void onGatewayConnection(const TModuleGatewayProxyPtr &serverGateway, TModuleGatewayConstant connectionResult)
217 // {
218 // nlstop;
219 // }
220 // virtual void onGatewayDisconnection(const TModuleGatewayProxyPtr &serverGateway)
221 // {
222 // nlstop;
223 // }
224 virtual void onAddModuleProxy(IModuleProxy *addedModule)
226 // always disclose module to local modules
227 discloseModule(addedModule);
229 virtual void onRemoveModuleProxy(IModuleProxy * /* removedModule */)
232 virtual void discloseModule(IModuleProxy *moduleProxy)
234 // check that the module is plugged here
235 nlassert(_ModuleProxies.getB(moduleProxy) != NULL);
237 // CModuleProxy *modProx = dynamic_cast<CModuleProxy *>(moduleProxy);
238 // nlassert(modProx != NULL);
239 nlassert(moduleProxy->getModuleGateway() == this);
241 // warn any plugged module
242 TPluggedModules::TAToBMap::const_iterator first(_PluggedModules.getAToBMap().begin()), last(_PluggedModules.getAToBMap().end());
243 for (; first != last; ++first)
245 IModule *module = first->second;
246 if (module->getModuleId() != moduleProxy->getForeignModuleId())
248 module->_onModuleUp(moduleProxy);
252 virtual IModuleProxy *getPluggedModuleProxy(IModule * /* pluggedModule */)
254 return NULL;
257 virtual uint32 getProxyCount() const
259 return (uint32)_ModuleProxies.getAToBMap().size();
262 /// Fill a vector with the list of proxies managed here. The module are filled in ascending proxy id order.
263 virtual void getModuleProxyList(std::vector<IModuleProxy*> &resultList) const
265 map<TModuleId, IModuleProxy*> index;
267 TModuleProxies::TAToBMap::const_iterator first(_ModuleProxies.getAToBMap().begin()), last(_ModuleProxies.getAToBMap().end());
268 for (; first != last; ++first)
270 index.insert(make_pair(first->first->getModuleProxyId(), first->first));
274 // now build the vector
275 map<TModuleId, IModuleProxy*>::iterator first(index.begin()), last(index.end());
276 for( ; first != last; ++first)
278 resultList.push_back(first->second);
283 // virtual void onReceiveModuleMessage(TModuleGatewayProxyPtr &senderGateway, TModuleMessagePtr &message)
284 // {
285 // }
286 virtual void sendModuleProxyMessage(IModuleProxy * /* senderProxy */, IModuleProxy * /* addresseeProxy */, const CMessage &/* message */)
289 virtual void dispatchModuleMessage(IModuleProxy * /* senderProxy */, IModuleProxy * /* addresseeProxy */, const CMessage &/* message */)
291 nlstop;
292 // TModuleId sourceId = message->getSenderModuleProxyId();
293 // TModuleProxies::TAToBMap::const_iterator firstSource(_ModuleProxies.getAToBMap().begin()), lastSource(_ModuleProxies.getAToBMap().end());
294 // for (; firstSource != lastSource && firstSource->first->getForeignModuleId() != sourceId; ++firstSource) {}
295 // nlassert( firstSource != lastSource );
297 // TPluggedModules::iterator first(_PluggedModules.begin()), last(_PluggedModules.end());
298 // TModuleId destId = message->getAddresseeModuleProxyId();
299 // for (; first != last && (*first)->getModuleId() != destId; ++first) {}
300 // if (first != last)
301 // {
302 // (*first)->onProcessModuleMessage(firstSource->first, message);
303 // }
305 /***********************************************************
306 ** Module methods
307 ***********************************************************/
308 bool initModule(const TParsedCommandLine &initInfo)
310 bool ret = CModuleBase::initModule(initInfo);
312 // in fact, this gateway is so simple, that it have no option !
314 registerSocket();
315 registerGateway();
317 return ret;
320 std::string buildModuleManifest() const
322 return string();
325 void onServiceUp(const std::string &/* serviceName */, NLNET::TServiceId /* serviceId */)
328 void onServiceDown(const std::string &/* serviceName */, NLNET::TServiceId /* serviceId */)
331 void onModuleUpdate()
334 void onApplicationExit()
337 void onModuleUp(IModuleProxy * /* moduleProxy */)
340 void onModuleDown(IModuleProxy * /* moduleProxy */)
343 bool onProcessModuleMessage(IModuleProxy * /* senderModuleProxy */, const CMessage &/* message */)
345 return false;
347 void onModuleSecurityChange(IModuleProxy * /* moduleProxy */)
350 void onModuleSocketEvent(IModuleSocket * /* moduleSocket */, TModuleSocketEvent /* eventType */)
354 /***********************************************************
355 ** Socket methods
356 ***********************************************************/
358 const std::string &getSocketName()
360 return getModuleName();
363 void _sendModuleMessage(IModule *senderModule, TModuleId destModuleProxyId, const NLNET::CMessage &message)
365 TModuleProxies::TAToBMap::const_iterator first(_ModuleProxies.getAToBMap().begin()), last(_ModuleProxies.getAToBMap().end());
366 for (; first != last && first->first->getModuleProxyId() != destModuleProxyId; ++first) {}
367 if (first != last) { first->first->sendModuleMessage(senderModule, message); return;}
368 throw EModuleNotReachable();
370 virtual void _broadcastModuleMessage(IModule * /* senderModule */, const NLNET::CMessage &/* message */)
372 nlstop;
375 void onModulePlugged(IModule *pluggedModule)
377 // A module has just been plugged here, we need to disclose it to the
378 // other module, and disclose other module to it.
380 // create a proxy for this module
381 IModuleProxy *modProx = IModuleManager::getInstance().createModuleProxy(
382 this,
383 NULL, // the module is local, so there is no route
384 0, // the module is local, distance is 0
385 pluggedModule, // the module is local, so store the module pointer
386 pluggedModule->getModuleClassName(),
387 getGatewayName()+"/"+pluggedModule->getModuleFullyQualifiedName(),
388 pluggedModule->getModuleManifest(),
389 // _ThisProxy,
390 pluggedModule->getModuleId());
392 // and store it
393 _ModuleProxies.add(modProx, CStringMapper::map(modProx->getModuleName()));
395 // disclose the new module to other modules
396 discloseModule(modProx);
398 // second, disclose already plugged proxy to the new one
400 TModuleProxies::TAToBMap::const_iterator first(_ModuleProxies.getAToBMap().begin()), last(_ModuleProxies.getAToBMap().end());
401 for (; first != last; ++first)
403 if (first->first->getModuleName() != pluggedModule->getModuleFullyQualifiedName())
404 pluggedModule->_onModuleUp(first->first);
410 /// Called just after a module as been effectively unplugged from a socket
411 void onModuleUnplugged(IModule *unpluggedModule)
413 // remove the proxy info
414 TModuleProxies::TBToAMap::const_iterator it(_ModuleProxies.getBToAMap().find(CStringMapper::map(getGatewayName()+"/"+unpluggedModule->getModuleFullyQualifiedName())));
415 nlassert(it != _ModuleProxies.getBToAMap().end());
417 IModuleProxy *modProx = it->second;
418 // warn all connected module that a module become unavailable
420 TPluggedModules::TAToBMap::const_iterator first(_PluggedModules.getAToBMap().begin()), last(_PluggedModules.getAToBMap().end());
421 for (; first != last; ++first)
423 IModule *module = first->second;
424 if (module->getModuleFullyQualifiedName() != modProx->getModuleName())
425 module->_onModuleDown(it->second);
429 // warn the unplugged module that all plugged modules are become unavailable
431 TModuleProxies::TAToBMap::const_iterator first(_ModuleProxies.getAToBMap().begin()), last(_ModuleProxies.getAToBMap().end());
432 for (; first != last; ++first)
434 if (first->first->getModuleName() != unpluggedModule->getModuleFullyQualifiedName())
435 unpluggedModule->_onModuleDown(first->first);
439 TModuleId localProxyId = modProx->getModuleProxyId();
440 // remove reference to the proxy
441 _ModuleProxies.removeWithA(modProx);
443 // release the module proxy
444 IModuleManager::getInstance().releaseModuleProxy(localProxyId);
448 void getModuleList(std::vector<IModuleProxy*> &resultList)
450 TModuleProxies::TAToBMap::const_iterator first(_ModuleProxies.getAToBMap().begin()), last(_ModuleProxies.getAToBMap().end());
451 for (; first != last; ++first)
453 resultList.push_back(first->first);
460 // register the module factory
461 NLNET_REGISTER_MODULE_FACTORY(CLocalGateway, "LocalGateway");
463 void forceLocalGatewayLink()
467 } // namespace NLNET