1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
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"
25 using namespace NLMISC
;
33 /** A simple gateway that interconnect module locally
34 * For testing purpose and simple case.
38 public CModuleGateway
,
41 // the proxy that represent this gateway
42 // TModuleGatewayProxyPtr _ThisProxy;
44 typedef CTwinMap
<TModuleProxyPtr
, TStringId
> TModuleProxies
;
45 // The modules proxies
46 TModuleProxies _ModuleProxies
;
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
69 /***********************************************************
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()
83 // nlassert(!_ThisProxy.isNull());
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 */)
103 /// Activate/stop firewalling mode on a transport
104 virtual void setTransportFirewallMode(const std::string
&/* transportInstanceName */, bool /* firewalled */)
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
120 virtual uint32
getTransportCount() const
125 virtual uint32
getRouteCount() const
130 virtual uint32
getReceivedPingCount() const
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()
165 // virtual CInetAddress getGatewayServerAddress()
167 // CInetAddress invalid;
171 // virtual void getGatewayClientList(std::vector<TModuleGatewayProxyPtr> gatewayList)
175 // virtual void openGatewayServer(uint16 listeningPort)
179 // virtual void closeGatewayServer()
183 // virtual void shutdownGatewayServer()
187 // virtual void onGatewayServerOpen()
190 // virtual void onGatewayServerClose()
193 // virtual TModuleGatewayConstant onClientGatewayConnect(TModuleGatewayProxyPtr &clientGateway)
195 // return mgc_reject_connection;
197 // virtual void onClientGatewayDisconnect(TModuleGatewayProxyPtr &clientGateway)
200 // virtual void getGatewayServerList(std::vector<TModuleGatewayProxyPtr> serverList)
204 // virtual bool isGatewayConnected()
208 // virtual void connectGateway(CInetAddress serverAddress)
212 // virtual void disconnectGateway(TModuleGatewayProxyPtr &serverGateway)
216 // virtual void onGatewayConnection(const TModuleGatewayProxyPtr &serverGateway, TModuleGatewayConstant connectionResult)
220 // virtual void onGatewayDisconnection(const TModuleGatewayProxyPtr &serverGateway)
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 */)
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)
286 virtual void sendModuleProxyMessage(IModuleProxy
* /* senderProxy */, IModuleProxy
* /* addresseeProxy */, const CMessage
&/* message */)
289 virtual void dispatchModuleMessage(IModuleProxy
* /* senderProxy */, IModuleProxy
* /* addresseeProxy */, const CMessage
&/* message */)
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)
302 // (*first)->onProcessModuleMessage(firstSource->first, message);
305 /***********************************************************
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 !
320 std::string
buildModuleManifest() const
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 */)
347 void onModuleSecurityChange(IModuleProxy
* /* moduleProxy */)
350 void onModuleSocketEvent(IModuleSocket
* /* moduleSocket */, TModuleSocketEvent
/* eventType */)
354 /***********************************************************
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 */)
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(
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(),
390 pluggedModule
->getModuleId());
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()