Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib2/src/libraries/network/MasterServerComm.cc @ 8703

Last change on this file since 8703 was 8311, checked in by rgrieder, 14 years ago

svn:eol-style "native" for all text based files.
Also removed the executable property from planets.oxw.

  • Property svn:eol-style set to native
File size: 7.2 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"
[8284]30#include "util/Debug.h"
[7589]31
[7631]32namespace orxonox
[7589]33{
[7768]34
[7631]35  MasterServerComm::MasterServerComm()
36  { /* nothing anymore, everything's been outsourced to
37     * the initialize method to facilitate debugging
38     */
[7768]39    /* register object in orxonox */
[7631]40  } 
[7589]41
[7631]42  int MasterServerComm::initialize()
43  {
44    /* initialize Enet */
[7763]45    if( enet_initialize () != 0 )
[7631]46    { COUT(1) << "An error occurred while initializing ENet.\n";
47      return 1;
48    }
[7684]49
50    /* initialize the event holder */
[7801]51//     this->event = (ENetEvent *)calloc( sizeof(ENetEvent), 1 );
[7631]52   
[7589]53
[7631]54    /* initiate the client */
55    this->client = enet_host_create( NULL /* create a client host */,
56        1,
57        2, /* allow up 2 channels to be used, 0 and 1 */
58        0, 
59        0 ); 
60
61    /* see if it worked */
62    if (this->client == NULL)
[7763]63    { COUT(1) << "An error occurred while trying to create an " 
64        << "ENet client host.\n";
[7631]65      return 1;
66    }
[7632]67
68    return 0;
[7589]69  }
70
[7631]71  MasterServerComm::~MasterServerComm()
72  {
73    /* destroy the enet facilities */
74    enet_host_destroy(this->client);
75  }
[7589]76
[7725]77  int MasterServerComm::connect( const char *address, unsigned int port )
[7631]78  {
79    /* Connect to address:port. */
80    enet_address_set_host( &this->address, address );
81    this->address.port = port;
[7589]82
[7631]83    /* Initiate the connection, allocating the two channels 0 and 1. */
84    this->peer = enet_host_connect(this->client, &this->address, 2, 0);   
[7589]85
[7763]86    if( this->peer == NULL )
87    { COUT(2) << "ERROR: No available peers for initiating an ENet"
88        << " connection.\n";
[7756]89      return -1;
[7631]90    }
[7589]91
[7631]92    /* Wait up to 2 seconds for the connection attempt to succeed. */
[7801]93    if (enet_host_service (this->client, &this->event, 500) > 0 &&
94        this->event.type == ENET_EVENT_TYPE_CONNECT )
[7745]95      COUT(3) << "Connection to master server succeeded.\n";
[7631]96    else
97    {
98      enet_peer_reset (this->peer);
[7745]99      COUT(2) << "ERROR: connection to " << address << " failed.\n";
[7631]100      return -1;
101    }
102
[7756]103    /* all fine */
[7631]104    return 0;
[7611]105  }
[7801]106 
107void MasterServerComm::update()
108{
109  while( enet_host_service( this->client, &this->event, 1 ) );
110}
[7589]111
[7801]112
[7761]113  int MasterServerComm::disconnect( void )
114  {
[7801]115    while( enet_host_service( this->client, &this->event, 1 ) );
[7761]116    enet_peer_disconnect( this->peer, 0 );
117
118    /* Allow up to 1 second for the disconnect to succeed
119     * and drop any packets received packets.
120     */
[7801]121    while (enet_host_service (this->client, &this->event, 1000) > 0)
[7761]122    {
[7801]123      switch (this->event.type)
[7761]124      {
125        case ENET_EVENT_TYPE_RECEIVE:
[7801]126          enet_packet_destroy (event.packet);
[7761]127          break;
128
129        case ENET_EVENT_TYPE_DISCONNECT:
130          COUT(4) << "Disconnect from master server successful.\n"; 
131          return 0;
132        default: break;
133      }
134    }
135
136    /* We've arrived here, so the disconnect attempt didn't
137     * succeed yet, hence: force the connection down.           
138     */
139    enet_peer_reset( this->peer );
140
141    /* done */
142    return 0;
143  }
144
[7756]145  /* NOTE this is to be reimplemented soon to return
146   * a structure containing
147   * - addrconv
148   * - the event
149   * so we can also make callbacks from objects
150   */
151  int MasterServerComm::pollForReply( int (*callback)( char*, ENetEvent* ),
152    int delayms )
[7611]153  { 
[7631]154    /* see whether anything happened */
[7668]155    /* WORK MARK REMOVE THIS OUTPUT */
[7692]156    COUT(2) << "polling masterserver...\n";
[7668]157
[7692]158    /* address buffer */
159    char *addrconv = NULL;
160    int retval = 0;
161
[7672]162    /* enet_host_service returns 0 if no event occured */
163    /* just newly set below test to >0 from >= 0, to be tested */
[7801]164    if( enet_host_service( this->client, &this->event, delayms ) > 0 )
[7631]165    { 
166      /* check what type of event it is and react accordingly */
[7801]167      switch (this->event.type)
[7631]168      { /* new connection, not supposed to happen. */
169        case ENET_EVENT_TYPE_CONNECT: break;
[7611]170
[7631]171        /* disconnect */
172        case ENET_EVENT_TYPE_DISCONNECT: /* ?? */ break;
173
[7611]174        /* incoming data */
[7631]175        case ENET_EVENT_TYPE_RECEIVE: 
176          addrconv = (char *) calloc( 50, 1 );
[7692]177          if( !addrconv ) 
178          { COUT(2) << "MasterServerComm.cc: Could not allocate memory!\n";
179            break;
180          }
181
182          /* resolve IP */
[7801]183          enet_address_get_host_ip( &(this->event.peer->address), 
[7684]184            addrconv, 49 );
[7611]185
[7631]186          /* DEBUG */
[7756]187          COUT(3) << "MasterServer Debug: A packet of length " 
[7801]188            << this->event.packet->dataLength
189            << " containing " << this->event.packet->data
[7725]190            << " was received from " << addrconv
[7801]191            << " on channel " << this->event.channelID;
[7631]192          /* END DEBUG */
[7611]193
[7631]194          /* call the supplied callback, if any. */
195          if( (*callback) != NULL )
[7801]196            retval = (*callback)( addrconv, &(this->event) );
[7611]197
[7756]198          /* clean up */
[7801]199          enet_packet_destroy( event.packet );
[7756]200          if( addrconv ) 
201            free( addrconv );
202
[7631]203          break;
204        default: break;
205      }
206
207      /* event handled, return 0 */
[7650]208      return retval;
[7589]209    }
[7631]210
211    /* show that no event occured */
[7668]212    return 0;
[7589]213  }
[7611]214
[7725]215  int MasterServerComm::sendRequest( const char *data )
[7631]216  {
217    /* send the data to the friend */
218    /* Create a reliable packet of size 7 containing "packet\0" */
219    ENetPacket * packet = enet_packet_create( data, 
220        strlen( data ) + 1, 
221        ENET_PACKET_FLAG_RELIABLE);
[7611]222
[7631]223    /* Send the packet to the peer over channel id 0. */
224    enet_peer_send (this->peer, 0, packet);
[7611]225
[7631]226    /* One could just use enet_host_service() instead. */
227    enet_host_flush( this->client );
[7668]228   
[7692]229    /* free the packet */
[7801]230    // PLEASE: never do this, because enet will free the packet once it's delivered. this will cause double frees
231//     enet_packet_destroy( packet );
[7632]232
233    /* all done. */
234    return 0;
[7631]235  }
[7611]236
[7650]237  int MasterServerComm::sendRequest( std::string data )
238  {
239    /* send the data to the friend */
240    /* Create a reliable packet of size 7 containing "packet\0" */
241    ENetPacket * packet = enet_packet_create( data.c_str(), 
242        data.length() + 1, 
243        ENET_PACKET_FLAG_RELIABLE);
244
245    /* Send the packet to the peer over channel id 0. */
246    enet_peer_send (this->peer, 0, packet);
247
248    /* One could just use enet_host_service() instead. */
249    enet_host_flush( this->client );
[7801]250    // PLEASE: never do this, because enet will free the packet once it's delivered. this will cause double frees
251//     enet_packet_destroy( packet );
[7650]252
253    /* all done. */
254    return 0;
255  }
256
[7611]257}
Note: See TracBrowser for help on using the repository browser.