Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

fixes

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