Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/libraries/network/MasterServerComm.cc @ 7764

Last change on this file since 7764 was 7763, checked in by smerkli, 14 years ago

disconnect implemented, switching to only use the MSC object of wandiscovery.

File size: 6.8 KB
RevLine 
[7589]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Sandro 'smerkli' Merkli
24 *   Co-authors:
25 *      ...
26 *
27 */
28
[7611]29#include "MasterServerComm.h"
[7589]30
[7631]31namespace orxonox
[7589]32{
[7631]33 
34  MasterServerComm::MasterServerComm()
35  { /* nothing anymore, everything's been outsourced to
36     * the initialize method to facilitate debugging
37     */
38  } 
[7589]39
[7631]40  int MasterServerComm::initialize()
41  {
42    /* initialize Enet */
[7763]43    if( enet_initialize () != 0 )
[7631]44    { COUT(1) << "An error occurred while initializing ENet.\n";
45      return 1;
46    }
[7684]47
48    /* initialize the event holder */
49    this->event = (ENetEvent *)calloc( sizeof(ENetEvent), 1 );
[7631]50   
[7589]51
[7631]52    /* initiate the client */
53    this->client = enet_host_create( NULL /* create a client host */,
54        1,
55        2, /* allow up 2 channels to be used, 0 and 1 */
56        0, 
57        0 ); 
58
59    /* see if it worked */
60    if (this->client == NULL)
[7763]61    { COUT(1) << "An error occurred while trying to create an " 
62        << "ENet client host.\n";
[7631]63      return 1;
64    }
[7632]65
66    return 0;
[7589]67  }
68
[7631]69  MasterServerComm::~MasterServerComm()
70  {
71    /* destroy the enet facilities */
72    enet_host_destroy(this->client);
73  }
[7589]74
[7725]75  int MasterServerComm::connect( const char *address, unsigned int port )
[7631]76  {
77    /* Connect to address:port. */
78    enet_address_set_host( &this->address, address );
79    this->address.port = port;
[7589]80
[7631]81    /* Initiate the connection, allocating the two channels 0 and 1. */
82    this->peer = enet_host_connect(this->client, &this->address, 2, 0);   
[7589]83
[7763]84    if( this->peer == NULL )
85    { COUT(2) << "ERROR: No available peers for initiating an ENet"
86        << " connection.\n";
[7756]87      return -1;
[7631]88    }
[7589]89
[7631]90    /* Wait up to 2 seconds for the connection attempt to succeed. */
[7684]91    if (enet_host_service (this->client, this->event, 2000) > 0 &&
92        this->event->type == ENET_EVENT_TYPE_CONNECT )
[7745]93      COUT(3) << "Connection to master server succeeded.\n";
[7631]94    else
95    {
96      enet_peer_reset (this->peer);
[7745]97      COUT(2) << "ERROR: connection to " << address << " failed.\n";
[7631]98      return -1;
99    }
100
[7756]101    /* all fine */
[7631]102    return 0;
[7611]103  }
[7589]104
[7761]105  int MasterServerComm::disconnect( void )
106  {
107    enet_peer_disconnect( this->peer, 0 );
108
109    /* Allow up to 1 second for the disconnect to succeed
110     * and drop any packets received packets.
111     */
112    while (enet_host_service (this->client, this->event, 1000) > 0)
113    {
114      switch (this->event->type)
115      {
116        case ENET_EVENT_TYPE_RECEIVE:
117          enet_packet_destroy (event->packet);
118          break;
119
120        case ENET_EVENT_TYPE_DISCONNECT:
121          COUT(4) << "Disconnect from master server successful.\n"; 
122          return 0;
123        default: break;
124      }
125    }
126
127    /* We've arrived here, so the disconnect attempt didn't
128     * succeed yet, hence: force the connection down.           
129     */
130    enet_peer_reset( this->peer );
131
132    /* done */
133    return 0;
134  }
135
[7756]136  /* NOTE this is to be reimplemented soon to return
137   * a structure containing
138   * - addrconv
139   * - the event
140   * so we can also make callbacks from objects
141   */
142  int MasterServerComm::pollForReply( int (*callback)( char*, ENetEvent* ),
143    int delayms )
[7611]144  { 
[7631]145    /* see whether anything happened */
[7668]146    /* WORK MARK REMOVE THIS OUTPUT */
[7692]147    COUT(2) << "polling masterserver...\n";
[7668]148
[7692]149    /* address buffer */
150    char *addrconv = NULL;
151    int retval = 0;
152
[7672]153    /* enet_host_service returns 0 if no event occured */
154    /* just newly set below test to >0 from >= 0, to be tested */
[7756]155    if( enet_host_service( this->client, this->event, delayms ) > 0 )
[7631]156    { 
157      /* check what type of event it is and react accordingly */
[7684]158      switch (this->event->type)
[7631]159      { /* new connection, not supposed to happen. */
160        case ENET_EVENT_TYPE_CONNECT: break;
[7611]161
[7631]162        /* disconnect */
163        case ENET_EVENT_TYPE_DISCONNECT: /* ?? */ break;
164
[7611]165        /* incoming data */
[7631]166        case ENET_EVENT_TYPE_RECEIVE: 
167          addrconv = (char *) calloc( 50, 1 );
[7692]168          if( !addrconv ) 
169          { COUT(2) << "MasterServerComm.cc: Could not allocate memory!\n";
170            break;
171          }
172
173          /* resolve IP */
[7684]174          enet_address_get_host_ip( &(this->event->peer->address), 
175            addrconv, 49 );
[7611]176
[7631]177          /* DEBUG */
[7756]178          COUT(3) << "MasterServer Debug: A packet of length " 
179            << this->event->packet->dataLength
[7725]180            << " containing " << this->event->packet->data
181            << " was received from " << addrconv
182            << " on channel " << this->event->channelID;
[7631]183          /* END DEBUG */
[7611]184
[7631]185          /* call the supplied callback, if any. */
186          if( (*callback) != NULL )
[7684]187            retval = (*callback)( addrconv, (this->event) );
[7611]188
[7756]189          /* clean up */
[7684]190          enet_packet_destroy( event->packet );
[7756]191          if( addrconv ) 
192            free( addrconv );
193
[7631]194          break;
195        default: break;
196      }
197
198      /* event handled, return 0 */
[7650]199      return retval;
[7589]200    }
[7631]201
202    /* show that no event occured */
[7668]203    return 0;
[7589]204  }
[7611]205
[7725]206  int MasterServerComm::sendRequest( const char *data )
[7631]207  {
208    /* send the data to the friend */
209    /* Create a reliable packet of size 7 containing "packet\0" */
210    ENetPacket * packet = enet_packet_create( data, 
211        strlen( data ) + 1, 
212        ENET_PACKET_FLAG_RELIABLE);
[7611]213
[7631]214    /* Send the packet to the peer over channel id 0. */
215    enet_peer_send (this->peer, 0, packet);
[7611]216
[7631]217    /* One could just use enet_host_service() instead. */
218    enet_host_flush( this->client );
[7668]219   
[7692]220    /* free the packet */
221    enet_packet_destroy( packet );
[7632]222
223    /* all done. */
224    return 0;
[7631]225  }
[7611]226
[7650]227  int MasterServerComm::sendRequest( std::string data )
228  {
229    /* send the data to the friend */
230    /* Create a reliable packet of size 7 containing "packet\0" */
231    ENetPacket * packet = enet_packet_create( data.c_str(), 
232        data.length() + 1, 
233        ENET_PACKET_FLAG_RELIABLE);
234
235    /* Send the packet to the peer over channel id 0. */
236    enet_peer_send (this->peer, 0, packet);
237
238    /* One could just use enet_host_service() instead. */
239    enet_host_flush( this->client );
[7763]240    enet_packet_destroy( packet );
[7650]241
242    /* all done. */
243    return 0;
244  }
245
[7611]246}
Note: See TracBrowser for help on using the repository browser.