00001 /*! 00002 * \file 00003 * X-Forge Engine <br> 00004 * Copyright 2000-2002 Fathammer Ltd 00005 * 00006 * \brief Default implementation for a inet communication manager. 00007 * 00008 * $Id: XFuInetNetwork.cpp,v 1.3 2003/10/08 11:08:34 slehti Exp $ 00009 * $Date: 2003/10/08 11:08:34 $ 00010 * $Revision: 1.3 $ 00011 */ 00012 00013 #include <xforge.h> 00014 00015 #include <xfcore/net/XFcInetHandler.h> 00016 #include <xfcore/net/XFcInetClientWin.h> 00017 #include <xfcore/net/XFcObjectDataFrame.h> 00018 #include <xfcore/net/XFcCommunicationScheduler.h> 00019 #include <xfcore/net/XFcCommunicationConstants.h> 00020 #include <xfcore/net/socket/XFcSocketConstants.h> 00021 #include <xfcore/net/XFcUnknownSender.h> 00022 #include <xfcore/net/XFcClientLost.h> 00023 #include <xfcore/net/XFcDataReceiver.h> 00024 #include <xfcore/net/XFcObjectDataFrame.h> 00025 #include <xfcore/net/socket/XFcInetHostEntry.h> 00026 #include <xfcore/net/socket/XFcInetHostResolver.h> 00027 #include <xfcore/net/socket/XFcInetAdvertiser.h> 00028 #include <xfcore/net/XFcUdpEngine.h> 00029 #include <xfcore/net/socket/XFcInetCommService.h> 00030 00031 #include <xfutil/XFuSerializable.h> 00032 #include <xfutil/XFuNetwork.h> 00033 #include <xfutil/XFuNetworkEventHandler.h> 00034 #include <xfutil/XFuInetNetwork.h> 00035 00036 00037 //! Static constructor 00038 XFuInetNetwork * XFuInetNetwork::create() 00039 { 00040 XFuInetNetwork * manager = new XFuInetNetwork; 00041 if (manager != NULL && !manager->init()) 00042 { 00043 delete manager; 00044 return NULL; 00045 } 00046 return manager; 00047 } 00048 00049 00050 //! Protected constructor 00051 XFuInetNetwork::XFuInetNetwork() 00052 { 00053 mNetworkEventHandlers = NULL; 00054 mCommunicationScheduler = NULL; 00055 mCommunicationHandler = NULL; 00056 00057 mAdvertiserStatus = 0; 00058 00059 mHostResolver = NULL; 00060 mMaxClients = -1; 00061 mAcceptGameToken = 0; 00062 00063 mCommunicationHandlerId = -1; 00064 00065 mCommService = NULL; 00066 00067 } 00068 00069 00070 //! Destructor 00071 XFuInetNetwork::~XFuInetNetwork() 00072 { 00073 closeService(); 00074 deleteAllClients(); 00075 removeAllEventHandlers(); 00076 00077 delete mHostResolver; 00078 delete mNetworkEventHandlers; 00079 delete mCommunicationHandler; 00080 delete mCommService; 00081 00082 } 00083 00084 00085 //! Initializes default communication manager specific items that would normally be in the constructor 00086 INT XFuInetNetwork::init() 00087 { 00088 00089 mCommunicationScheduler = (XFcCommunicationScheduler *)XFcCore::getCommunicationScheduler(); 00090 if (mNetworkEventHandlers == NULL) 00091 mNetworkEventHandlers = XFuDynamicArray<XFuNetworkEventHandler*>::create(5); 00092 00093 if (mCommunicationScheduler == NULL || 00094 mNetworkEventHandlers == NULL) return 0; 00095 00096 return 1; 00097 00098 } 00099 00100 00101 //! Runs the communication scheduler 00102 void XFuInetNetwork::runCommunicationScheduler() 00103 { 00104 mCommunicationScheduler->runScheduler(); 00105 } 00106 00107 00108 //! Resets the communication manager 00109 void XFuInetNetwork::reset() 00110 { 00111 closeService(); 00112 removeAllClients(); 00113 removeAllEventHandlers(); 00114 mMaxClients = -1; 00115 mAcceptGameToken = 0; 00116 init(); 00117 } 00118 00119 00120 00121 //! Enables the inet communication handler and opens it for service. Use port 0 for random port. 00122 //! Default speed is one of the XFCNET_CONNECTION_SPEED values (see XFcClientCommWin.h) 00123 INT XFuInetNetwork::enableService(INT32 aMaxClients, UINT16 aPort, INT32 aDefaultSpeed) 00124 { 00125 closeService(); 00126 removeAllClients(); 00127 00128 00129 mCommunicationHandler = XFcInetHandler::create(); 00130 mCommService = XFcInetCommService::create(); 00131 00132 if (mCommunicationHandler && mCommService) 00133 { 00134 00135 if (aPort != 0) 00136 mCommunicationHandler->setPort(aPort); 00137 00138 mGamePort = aPort; 00139 00140 mCommunicationHandler->setConnectionSpeed(aDefaultSpeed); 00141 mCommunicationHandler->setUnknownSenderHandler(this); 00142 mCommunicationHandler->setClientLost(this); 00143 mCommunicationHandler->setMaxClientCount(aMaxClients); 00144 00145 initClients(aMaxClients); 00146 00147 mCommunicationHandlerId = mCommunicationScheduler->addCommunicationHandler(mCommunicationHandler); 00148 mCommunicationHandler->openService(); 00149 00150 if (mCommunicationHandler->getLastError() != XFcUdpEngine::XFCNET_UDP_CLOSE) 00151 return 1; 00152 } 00153 return 0; 00154 } 00155 00156 00157 //! Closes the currently active service (communication handler) 00158 void XFuInetNetwork::closeService() 00159 { 00160 00161 stopAdvertiser(); 00162 stopServerDiscovery(); 00163 00164 if (mCommunicationHandler) 00165 { 00166 mCommunicationHandler->closeService(); 00167 mCommunicationScheduler->removeCommunicationHandler(mCommunicationHandlerId); 00168 delete mCommunicationHandler; 00169 mCommunicationHandler = NULL; 00170 } 00171 00172 delete mHostResolver; 00173 mHostResolver = NULL; 00174 delete mCommService; 00175 mCommService = NULL; 00176 00177 } 00178 00179 00180 //! Returns the game token that is checked before new clients are allowed to connect 00181 UINT32 XFuInetNetwork::getAcceptGameToken() 00182 { 00183 return mAcceptGameToken; 00184 } 00185 00186 //! Sets the game token that is checked before new clients are allowed to connect 00187 void XFuInetNetwork::setAcceptGameToken(UINT32 aAcceptGameToken) 00188 { 00189 mAcceptGameToken = aAcceptGameToken; 00190 } 00191 00192 00193 //! Sends a game connection packet 00194 void XFuInetNetwork::sendGameConnectPacket(INT32 aClientId, UINT32 aGameToken) 00195 { 00196 XFcObjectDataFrame *frame = getPacketFrame(aClientId, XFCNET_NONGUARANTEED); 00197 if (frame) 00198 { 00199 00200 frame->setReceiverId(0); 00201 void *buffer = frame->lock(); 00202 if (buffer) 00203 { 00204 memcpy(buffer, &aGameToken, 4); 00205 frame->setPacketSize(4); 00206 } 00207 frame->unlock(); 00208 } 00209 00210 } 00211 00212 00213 //! Reserves memory for the client array (mClients) and initializes all the client 00214 //! pointers to NULL 00215 void XFuInetNetwork::initClients(INT32 aMaxClients) 00216 { 00217 mMaxClients = aMaxClients; 00218 } 00219 00220 00221 //! Cleanup of all clients 00222 void XFuInetNetwork::deleteAllClients() 00223 { 00224 00225 XFcHashtableIterator<UINT32, XFcInetClientWin *> itClient; 00226 00227 while (mClients.size() > 0) 00228 { 00229 itClient = mClients.begin(); 00230 INT32 key = itClient.getKey(); 00231 XFcClientCommWin *base_client = getClient(key); 00232 mCommunicationScheduler->removeClient(key); 00233 base_client->deinitializeClient(); 00234 mClients.remove(key); 00235 delete base_client; 00236 } 00237 } 00238 00239 //! Removes all clients and frees the memory reserved by the clients and the client array (mClients) 00240 void XFuInetNetwork::removeAllClients() 00241 { 00242 00243 XFcHashtableIterator<UINT32, XFcInetClientWin *> itClient; 00244 00245 if (!mCommunicationHandler) 00246 return; 00247 00248 while (mClients.size() > 0) 00249 { 00250 itClient = mClients.begin(); 00251 INT32 key = itClient.getKey(); 00252 removeClient(key); 00253 } 00254 } 00255 00256 00257 //! Returns a pointer to the default data receiver 00258 XFcDataReceiver * XFuInetNetwork::getDefaultDataReceiver() 00259 { 00260 return mDefaultDataReceiver; 00261 } 00262 00263 00264 //! Sets the default data receiver 00265 void XFuInetNetwork::setDefaultDataReceiver(XFcDataReceiver *aReceiver) 00266 { 00267 mDefaultDataReceiver = aReceiver; 00268 mCommunicationScheduler->setDataReceiver(aReceiver); 00269 } 00270 00271 00272 //! Returns the specified data receiver 00273 XFcDataReceiver * XFuInetNetwork::getDataReceiver(UINT32 aId) 00274 { 00275 return mCommunicationScheduler->getDataReceiver(aId); 00276 } 00277 00278 00279 //! Adds a new data receiver 00280 INT XFuInetNetwork::addDataReceiver(UINT32 aId, XFcDataReceiver *aReceiver) 00281 { 00282 return mCommunicationScheduler->addDataReceiver(aId, aReceiver); 00283 } 00284 00285 00286 //! Removes a data receiver 00287 XFcDataReceiver * XFuInetNetwork::removeDataReceiver(UINT32 aId) 00288 { 00289 return mCommunicationScheduler->removeDataReceiver(aId); 00290 } 00291 00292 00293 //! Adds a communication event handler 00294 void XFuInetNetwork::addEventHandler(XFuNetworkEventHandler *aHandler) 00295 { 00296 mNetworkEventHandlers->put(aHandler); 00297 } 00298 00299 00300 //! Removes a communication event handler 00301 void XFuInetNetwork::removeEventHandler(XFuNetworkEventHandler *aHandler) 00302 { 00303 mNetworkEventHandlers->remove(aHandler); 00304 } 00305 00306 00307 //! Removes all communication event handlers 00308 void XFuInetNetwork::removeAllEventHandlers() 00309 { 00310 while (!mNetworkEventHandlers->isEmpty()) mNetworkEventHandlers->remove(); 00311 } 00312 00313 00314 //! Returns the specified client 00315 XFcClientCommWin * XFuInetNetwork::getClient(INT32 aClientId) 00316 { 00317 XFcHashtable<UINT32, XFcInetClientWin *>::iterator it; 00318 XFcClientCommWin * value = NULL; 00319 00320 it = mClients.find(aClientId); 00321 00322 if(it.isValid()) 00323 { 00324 value = it.getValue(); 00325 } 00326 00327 return value; 00328 00329 } 00330 00331 00332 //! Adds a client with the specific address. Returns the client id or XFCNET_CLIENTADD_ERROR if failed 00333 INT32 XFuInetNetwork::addClient(XFcAddress *aAddress, INT32 aTimeoutTime) 00334 { 00335 XFcInetClientWin *client = NULL; 00336 INT32 clientId = -1; 00337 00338 if (aAddress->getType() != (INT32)XFCNET_AFINET) 00339 return 0; 00340 00341 if ((client = XFcInetClientWin::create()) != NULL) 00342 { 00343 client->setAddress(*aAddress); 00344 client->setConnectionTimeout(aTimeoutTime); 00345 00346 if (((clientId = mCommunicationScheduler->addClient(client)) != XFCNET_CLIENTADD_ERROR && 00347 clientId != XFCNET_ERROR) && 00348 mClients.put(clientId, client)) 00349 { 00350 return clientId; 00351 } 00352 } 00353 delete client; 00354 return 0; 00355 } 00356 00357 00358 //! Removes the specified client 00359 void XFuInetNetwork::removeClient(INT32 aClientId) 00360 { 00361 if (!mCommunicationHandler) 00362 return; 00363 00364 XFcClientCommWin *client = NULL; 00365 00366 if ((client = getClient(aClientId)) != NULL) 00367 { 00368 mCommunicationScheduler->removeClient(aClientId); 00369 mClients.remove(aClientId); 00370 delete client; 00371 } 00372 } 00373 00374 00375 //! Returns the round trip time for the specified client 00376 INT32 XFuInetNetwork::getRoundTripTime(INT32 aClientId) 00377 { 00378 return mCommunicationScheduler->getRoundTripTime(aClientId); 00379 } 00380 00381 00382 //! Get packet frame 00383 XFcObjectDataFrame * XFuInetNetwork::getPacketFrame(INT32 aClientId, XFCNET_MESSAGE_SLOT aSlot) 00384 { 00385 return mCommunicationScheduler->getPacketFrame(aClientId, aSlot); 00386 } 00387 00388 00389 //! Get recent state frame 00390 XFcObjectDataFrame * XFuInetNetwork::getRecentStateFrame(INT32 aClientId, INT32 aRecentId) 00391 { 00392 return mCommunicationScheduler->getRecentStateFrame(aClientId, aRecentId); 00393 } 00394 00395 00396 //! Remove recent state frame 00397 void XFuInetNetwork::removeRecentStateFrame(INT32 aClientId, INT32 aRecentId) 00398 { 00399 mCommunicationScheduler->removeRecentStateFrame(aClientId, aRecentId); 00400 } 00401 00402 00403 //! Sends a serializable object to the specified client 00404 INT32 XFuInetNetwork::send(INT32 aClientId, UINT32 aReceiverId, XFCNET_MESSAGE_SLOT aSlot, XFuSerializable *aSerializable) 00405 { 00406 INT32 size = -1; 00407 XFcObjectDataFrame *frame = getPacketFrame(aClientId, aSlot); 00408 if (frame) 00409 { 00410 void *buffer = frame->lock(); 00411 if (buffer) 00412 { 00413 size = aSerializable->serialize((CHAR8*)buffer, frame->sizeofBuffer()); 00414 frame->setPacketSize(size); 00415 frame->setReceiverId(aReceiverId); 00416 00417 } 00418 frame->unlock(); 00419 } 00420 return size; 00421 } 00422 00423 00424 //! Sends a serializable object to the specified client as a recent state packet 00425 INT32 XFuInetNetwork::sendRecentState(INT32 aClientId, UINT32 aReceiverId, INT32 aRecentId, XFuSerializable *aSerializable) 00426 { 00427 INT32 size = -1; 00428 XFcObjectDataFrame *frame = getRecentStateFrame(aClientId, aRecentId); 00429 if (frame) 00430 { 00431 void *buffer = frame->lock(); 00432 if (buffer) 00433 { 00434 size = aSerializable->serialize((CHAR8*)buffer, frame->sizeofBuffer()); 00435 frame->setPacketSize(size); 00436 frame->setReceiverId(aReceiverId); 00437 } 00438 frame->unlock(); 00439 } 00440 return size; 00441 } 00442 00443 00444 //! Connection lost handler (XFuClientLost) 00445 void XFuInetNetwork::clientLost(INT32 aClientId) 00446 { 00447 removeClient(aClientId); 00448 INT32 handlersNum = mNetworkEventHandlers->size(); 00449 INT32 i; 00450 for (i = 0; i < handlersNum; i++) 00451 { 00452 mNetworkEventHandlers->get(i)->handleClientLost(aClientId); 00453 } 00454 } 00455 00456 00457 //! Handle data from an unknown client 00458 INT XFuInetNetwork::handleSender(const void *aAddress, const CHAR8 *aData, INT32 aLen) 00459 { 00460 00461 UINT32 gameToken; 00462 00463 if (((XFcAddress *)aAddress)->getType() != (INT32)XFCNET_AFINET) 00464 return 0; 00465 00466 if (aLen == 4) 00467 { 00468 memcpy(&gameToken, aData, 4); 00469 00470 if (gameToken == mAcceptGameToken) 00471 { 00472 INT32 clientId = addClient((XFcAddress*)aAddress); 00473 if (clientId != XFCNET_CLIENTADD_ERROR) 00474 { 00475 INT32 handlersNum = mNetworkEventHandlers->size(); 00476 INT32 i; 00477 for (i = 0; i < handlersNum; i++) 00478 { 00479 mNetworkEventHandlers->get(i)->handleClientAccepted(clientId); 00480 } 00481 } 00482 } 00483 } 00484 return 0; 00485 } 00486 00487 00488 INT XFuInetNetwork::startServerDiscovery(const CHAR8 *aMessage, UINT16 aAdvertisePort) 00489 { 00490 00491 INT retValue = 0; 00492 if (!mCommService) 00493 return 0; 00494 00495 XFcInetAdvertiser *inetAdvertise = NULL; 00496 00497 if (aMessage) 00498 inetAdvertise = XFcInetAdvertiser::create(aMessage, strlen(aMessage)); 00499 else 00500 { 00501 CHAR8 *string = "X-Forge server query"; 00502 inetAdvertise = XFcInetAdvertiser::create(string, 20); 00503 } 00504 00505 if (inetAdvertise) 00506 { 00507 inetAdvertise->setAdvertisePort(aAdvertisePort); 00508 retValue = mCommService->inquiry(*inetAdvertise, this); 00509 } 00510 00511 delete inetAdvertise; 00512 00513 return (retValue != XFCNET_ERROR) ? 1 : 0; 00514 } 00515 00516 void XFuInetNetwork::stopServerDiscovery() 00517 { 00518 if (!mCommService) 00519 return; 00520 mCommService->cancelInquiry(); 00521 } 00522 00523 INT XFuInetNetwork::startAdvertiser(const CHAR8 *aMessage, UINT16 aAdvertisePort) 00524 { 00525 INT retVal = XFCNET_ERROR; 00526 00527 if (!mCommService) 00528 return 0; 00529 00530 XFcInetAdvertiser *advertise = NULL; 00531 00532 if ((advertise = XFcInetAdvertiser::create()) != NULL) 00533 { 00534 if (aMessage == NULL) 00535 advertise->setMessageHeader("X-Forge server", 14); 00536 else 00537 advertise->setMessageHeader(aMessage, strlen(aMessage)); 00538 00539 advertise->setGamePort(mGamePort); 00540 advertise->setAdvertisePort(aAdvertisePort); 00541 00542 retVal = mCommService->advertise(*advertise); 00543 delete advertise; 00544 } 00545 return (retVal != XFCNET_ERROR) ? 1 : 0; 00546 } 00547 00548 00549 void XFuInetNetwork::stopAdvertiser() 00550 { 00551 if (!mCommService) 00552 return; 00553 00554 mCommService->cancelAdvertise(); 00555 } 00556 00557 00558 void XFuInetNetwork::deviceDiscovery(const XFcLinkedList<XFcAdvertiser *> &aAdvertiser) 00559 { 00560 XFcLinkedList<XFcAdvertiser *>::forwardIterator it; 00561 INT32 handlersNum = mNetworkEventHandlers->size(); 00562 INT32 i; 00563 00564 if (aAdvertiser.size() != 0) 00565 { 00566 for (it = aAdvertiser.forwardBegin(); it != aAdvertiser.forwardEnd(); it++) 00567 { 00568 for (i = 0; i < handlersNum; i++) 00569 mNetworkEventHandlers->get(i)->handleAdvertiseDiscovered(it.getData()); 00570 } 00571 } 00572 else 00573 { 00574 for (i = 0; i < handlersNum; i++) 00575 { 00576 mNetworkEventHandlers->get(i)->handleAdvertiseDiscovered(NULL); 00577 } 00578 } 00579 } 00580 00581 00582 INT XFuInetNetwork::deviceLocalName(XFcName &aName) 00583 { 00584 // Delete host resolver 00585 if (!mHostResolver) 00586 mHostResolver = XFcInetHostResolver::create(); 00587 00588 // Do the device discovery, async found devices are returned througth deviceDiscovery callback. 00589 if (mHostResolver) 00590 { 00591 INT error = mHostResolver->localName(aName); 00592 00593 if (error != XFCNET_ERROR) 00594 { 00595 if (aName.mLen < 0x40) 00596 aName.mName[aName.mLen] = '\0'; 00597 00598 return 1; 00599 } 00600 } 00601 return 0; 00602 } 00603
![]() | ||||
![]() |
Confidential Copyright © 2002-2003 Fathammer | with doxygen by Dimitri van Heesch |