Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/PresentationFS18/src/libraries/network/MasterServerComm.cc @ 12113

Last change on this file since 12113 was 12020, checked in by patricwi, 6 years ago

Merged Masterserver

  • Property svn:eol-style set to native
File size: 7.2 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/Output.h"
31#include "WANDiscovery.h"
32
33namespace orxonox
34{
35
36  MasterServerComm::MasterServerComm()
37  { /* nothing anymore, everything's been outsourced to
38     * the initialize method to facilitate debugging
39     */
40  } 
41
42  int MasterServerComm::initialize()
43  {
44    /* initialize Enet */
45    if( enet_initialize () != 0 )
46    { orxout(internal_error, context::master_server) << "An error occurred while initializing ENet." << endl;
47      return 1;
48    }
49
50    /* initiate the client */
51    this->client = enet_host_create( nullptr /* create a client host */,
52        1,
53        2, /* allow up 2 channels to be used, 0 and 1 */
54        0, 
55        0 ); 
56
57    /* see if it worked */
58    if (this->client == nullptr)
59    { orxout(internal_error, context::master_server) << "An error occurred while trying to create an " 
60        << "ENet client host." << endl;
61      return 1;
62    }
63
64    return 0;
65  }
66
67  MasterServerComm::~MasterServerComm()
68  {
69    /* destroy the enet facilities */
70    enet_host_destroy(this->client);
71  }
72
73  int MasterServerComm::connect( const char *address, unsigned int port )
74  {
75    /* Connect to address:port. */
76    enet_address_set_host( &this->address, address );
77    this->address.port = port;
78
79    /* Initiate the connection, allocating the two channels 0 and 1. */
80    this->peer = enet_host_connect(this->client, &this->address, 2, 0);   
81
82    if( this->peer == nullptr )
83    { orxout(internal_error, context::master_server) << "No available peers for initiating an ENet"
84        << " connection." << endl;
85      return -1;
86    }
87
88    /* Wait up to 2 seconds for the connection attempt to succeed. */
89    if (enet_host_service (this->client, &this->event, 500) > 0 &&
90        this->event.type == ENET_EVENT_TYPE_CONNECT )
91      orxout(internal_info, context::master_server) << "Connection to master server succeeded." << endl;
92    else
93    {
94      enet_peer_reset (this->peer);
95      orxout(internal_warning, context::master_server) << "Connection to " << address << " failed." << endl;
96      return -1;
97    }
98
99    /* all fine */
100    return 0;
101  }
102 
103void MasterServerComm::update()
104{
105  while( enet_host_service( this->client, &this->event, 1 ) );
106}
107
108
109  int MasterServerComm::disconnect( void )
110  {
111    while( enet_host_service( this->client, &this->event, 1 ) );
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          orxout(verbose, context::master_server) << "Disconnect from master server successful." << endl; 
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( WANDiscovery* listener, int delayms )
148  { 
149    /* see whether anything happened */
150    /* WORK MARK REMOVE THIS OUTPUT */
151    orxout(verbose, context::master_server) << "polling masterserver..." << endl;
152
153    /* address buffer */
154    char *addrconv = nullptr;
155    int retval = 0;
156
157    /* enet_host_service returns 0 if no event occured */
158    /* just newly set below test to >0 from >= 0, to be tested */
159    if( enet_host_service( this->client, &this->event, delayms ) > 0 )
160    { 
161      /* check what type of event it is and react accordingly */
162      switch (this->event.type)
163      { /* new connection, not supposed to happen. */
164        case ENET_EVENT_TYPE_CONNECT: break;
165
166        /* disconnect */
167        case ENET_EVENT_TYPE_DISCONNECT: /* ?? */ break;
168
169        /* incoming data */
170        case ENET_EVENT_TYPE_RECEIVE: 
171          addrconv = (char *) calloc( 50, 1 );
172          if( !addrconv ) 
173          { orxout(internal_warning, context::master_server) << "MasterServerComm.cc: Could not allocate memory!" << endl;
174            break;
175          }
176
177          /* resolve IP */
178          enet_address_get_host_ip( &(this->event.peer->address), 
179            addrconv, 49 );
180
181          /* DEBUG */
182          orxout(verbose, context::master_server) << "MasterServer Debug: A packet of length " 
183            << this->event.packet->dataLength
184            << " containing " << this->event.packet->data
185            << " was received from " << addrconv
186            << " on channel " << this->event.channelID;
187          /* END DEBUG */
188
189          /* call the supplied callback, if any. */
190          if( listener != nullptr )
191            retval = listener->rhandler( addrconv, &(this->event) );
192
193          /* clean up */
194          enet_packet_destroy( event.packet );
195          if( addrconv ) 
196            free( addrconv );
197
198          break;
199        default: break;
200      }
201
202      /* event handled, return 0 */
203      return retval;
204    }
205
206    /* show that no event occured */
207    return 0;
208  }
209
210  int MasterServerComm::sendRequest( const char *data )
211  {
212    /* send the data to the friend */
213    /* Create a reliable packet of size 7 containing "packet\0" */
214    ENetPacket * packet = enet_packet_create( data, 
215        strlen( data ) + 1, 
216        ENET_PACKET_FLAG_RELIABLE);
217
218    /* Send the packet to the peer over channel id 0. */
219    enet_peer_send (this->peer, 0, packet);
220
221    /* One could just use enet_host_service() instead. */
222    enet_host_flush( this->client );
223
224    /* all done. */
225    return 0;
226  }
227
228  int MasterServerComm::sendRequest( std::string data )
229  {
230    /* send the data to the friend */
231    /* Create a reliable packet of size 7 containing "packet\0" */
232    ENetPacket * packet = enet_packet_create( data.c_str(), 
233        data.length() + 1, 
234        ENET_PACKET_FLAG_RELIABLE);
235
236    /* Send the packet to the peer over channel id 0. */
237    enet_peer_send (this->peer, 0, packet);
238
239    /* One could just use enet_host_service() instead. */
240    enet_host_flush( this->client );
241
242    /* all done. */
243    return 0;
244  }
245
246}
Note: See TracBrowser for help on using the repository browser.