Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7761 was 7761, checked in by smerkli, 13 years ago

disconnect implemented, getting ready for testing.

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