Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/masterserver/src/modules/masterserver/MasterServer.cc @ 7692

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

done for today, didn't get bug to leave, and connect doesn't quite work yet.

File size: 8.5 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 "MasterServer.h"
30#include "util/ScopedSingletonManager.h"
31#include "core/CoreIncludes.h"
32#include "core/CorePrereqs.h"
33
34namespace orxonox
35{
36  /* singleton stuff */
37  //ManageScopedSingleton( MasterServer, ScopeID::Root, false );
38
39  /* helpers */
40  static void 
41  helper_output_debug( ENetEvent *event, char *addrconv )
42  {
43    COUT(4) << "A packet of length" 
44      << event->packet->dataLength
45      << " containing "
46      << (const char*)event->packet->data
47      << " was received from "
48      << addrconv
49      << " on channel "
50      << event->channelID << "\n";
51  }
52
53  void
54  MasterServer::helper_sendlist( ENetEvent *event )
55  {
56    /* get an iterator */
57    std::list<packet::ServerInformation>::iterator i;
58
59    /* packet holder */
60    ENetPacket *reply;
61
62    /* loop through list elements */
63    for( i = mainlist.serverlist.begin(); i
64        != mainlist.serverlist.end(); ++i ) 
65    {
66      /* WORK MARK */
67      /* send this particular server */
68      /* build reply string */
69      char *tosend = (char *)calloc( (*i).getServerIP().length() 
70          + MSPROTO_SERVERLIST_ITEM_LEN + 2,1 );
71      if( !tosend ) 
72      { COUT(2) << "Masterserver.cc: Memory allocation failed.\n";
73        continue;
74      } 
75      sprintf( tosend, "%s %s", MSPROTO_SERVERLIST_ITEM, 
76          (*i).getServerIP().c_str() );
77
78      /* create packet from it */
79      reply = enet_packet_create( tosend,
80          strlen( tosend ) + 1, 
81          ENET_PACKET_FLAG_RELIABLE);
82
83      /* Send the reply to the peer over channel id 0. */
84      enet_peer_send( event->peer, 0, reply );
85
86      /* One could just use enet_host_service() instead. */
87      enet_host_flush( this->server );
88
89      /* free the tosend buffer */
90      free( tosend );
91    } 
92
93    /* send end-of-list packet */
94    reply = enet_packet_create( MSPROTO_SERVERLIST_END,
95        MSPROTO_SERVERLIST_END_LEN + 1,
96        ENET_PACKET_FLAG_RELIABLE );
97
98    enet_peer_send( event->peer, 0, reply );
99
100    /* One could just use enet_host_service() instead. */
101    enet_host_flush( this->server );
102  }
103
104
105
106
107  /***** EVENTS *****/
108  /* connect event */
109  int 
110  MasterServer::eventConnect( ENetEvent *event )
111  { /* check for bad parameters */
112    if( !event )
113    { COUT(2) << "MasterServer::eventConnect: No event given.\n" ;
114      return -1;
115    }
116
117    /* convert address to string. */
118    char *addrconv = (char *) calloc( 50, 1 );
119    enet_address_get_host_ip( &(event->peer->address), addrconv, 49 );
120
121    /* output debug info */
122    COUT(4) << "A new client connected from " 
123      << addrconv
124      << " on port " 
125      << event->peer->address.port << "\n";
126
127    /* store string form of address here */
128    event->peer->data = addrconv; 
129
130    /* all fine. */
131    return 0;
132  }
133
134  /* disconnect event */
135  int 
136  MasterServer::eventDisconnect( ENetEvent *event )
137  { /* check for bad parameters */
138    if( !event )
139    { COUT(2) << "No event given.\n";
140      return -1;
141    }
142
143    /* output that the disconnect happened */
144    COUT(4) << (char*)event->peer->data << " disconnected.\n";
145
146    /* create string from peer data */
147    std::string name = std::string( (char*)event->peer->data );
148
149    /* remove the server from the list it belongs to */
150    this->mainlist.delServerByName( name );
151
152    /* Reset the peer's client information. */
153    if( event->peer->data ) free( event->peer->data );
154
155    /* done */
156    return 0;
157  }
158
159  /* data event */
160  int 
161  MasterServer::eventData( ENetEvent *event )
162  { /* validate packet */
163    if( !event || !(event->packet) || !(event->peer) )
164      //|| !(event->packet->data) || !strlen(event->packet->data) )
165    { COUT(2) << "No complete event given.\n";
166      return -1;
167    }
168     
169    /* generate address in readable form */
170    char *addrconv = (char *) calloc( 50, 1 );
171    enet_address_get_host_ip( &(event->peer->address), addrconv, 49 );
172
173    /* DEBUG */
174    /* output debug info about the data that has come, to be removed */
175    helper_output_debug( event, addrconv );
176
177    /* GAME SERVER OR CLIENT CONNECTION? */
178    if( !strncmp( (char *)event->packet->data, MSPROTO_GAME_SERVER, 
179      MSPROTO_GAME_SERVER_LEN ) )
180    { /* Game server */
181
182      if( !strncmp( (char *)event->packet->data
183        + MSPROTO_GAME_SERVER_LEN+1, 
184        MSPROTO_REGISTER_SERVER, MSPROTO_REGISTER_SERVER_LEN ) )
185      { /* register new server */
186        mainlist.addServer( packet::ServerInformation( event ) );
187       
188        /* tell people we did so */
189        COUT(2) << "Added new server to list: " << 
190          packet::ServerInformation( event ).getServerIP() << "\n";
191      }
192    }
193    else if( !strncmp( (char *)event->packet->data, MSPROTO_CLIENT, 
194      MSPROTO_CLIENT_LEN) )
195    { /* client */
196      if( !strncmp( (char *)event->packet->data + MSPROTO_CLIENT_LEN+1,
197        MSPROTO_REQ_LIST, MSPROTO_REQ_LIST_LEN ) )
198        /* send server list */
199        helper_sendlist( event );
200    }
201    else
202    { /* bad message, don't do anything. */ } 
203
204    /* delete addrconv */
205    if( addrconv ) free( addrconv );
206
207    /* Clean up the packet now that we're done using it. */
208    enet_packet_destroy( event->packet );
209    return 0;
210  }
211
212
213  /**** MAIN ROUTINE *****/
214  int 
215  MasterServer::run()
216  {
217    /***** ENTER MAIN LOOP *****/
218    ENetEvent *event = (ENetEvent *)calloc(sizeof(ENetEvent), sizeof(char));
219    if( event == NULL )
220    { 
221      COUT(1) << "Could not create ENetEvent structure, exiting.\n";
222      exit( EXIT_FAILURE );
223    }
224
225    /* tell people we're now initialized and blocking. */
226    COUT(0) << "MasterServer initialized, waiting for connections.\n";
227
228    /* create an iterator for the loop */
229    while( enet_host_service( this->server, event, 1000 ) >= 0 )
230    { /* check what type of event it is and react accordingly */
231      switch (event->type)
232      { /* new connection */
233        case ENET_EVENT_TYPE_CONNECT: 
234          eventConnect( event ); break;
235
236          /* disconnect */
237        case ENET_EVENT_TYPE_DISCONNECT: 
238          eventDisconnect( event ); break;
239
240          /* incoming data */
241        case ENET_EVENT_TYPE_RECEIVE: eventData( event ); break;
242        default: break;
243      }
244    }
245
246    /* free the event */
247    if( event ) free( event );
248
249    /* done */
250    return 0;
251  } 
252
253  /* constructor */
254  MasterServer::MasterServer()
255  {
256    /***** INITIALIZE NETWORKING *****/
257    if( enet_initialize () != 0)
258    { COUT(1) << "An error occurred while initializing ENet.\n";
259      exit( EXIT_FAILURE );
260    }
261
262    /* register deinitialization */
263    atexit( enet_deinitialize );
264
265    /* Bind the server to the default localhost and port ORX_MSERVER_PORT */
266    this->address.host = ENET_HOST_ANY;
267    this->address.port = ORX_MSERVER_PORT;
268
269    /* create a host with the above settings (the last two 0 mean: accept
270     * any input/output bandwidth */
271    this->server = enet_host_create( &this->address, ORX_MSERVER_MAXCONNS, 
272        ORX_MSERVER_MAXCHANS, 0, 0 );     
273
274    /* see if creation worked */
275    if( !this->server )
276    { COUT(1) << 
277        "An error occurred while trying to create an ENet server host.\n";
278      exit( EXIT_FAILURE );
279    }
280
281    /***** INITIALIZE GAME SERVER AND PEER LISTS *****/
282    //this->mainlist = new ServerList();
283    this->peers = new PeerList();
284    //if( this->mainlist == NULL || this->peers == NULL )
285    //{ COUT(1) << "Error creating server or peer list.\n";
286      //exit( EXIT_FAILURE );
287    //}
288
289    /* run the main method */
290    run();
291  }
292
293  /* destructor */
294  MasterServer::~MasterServer()
295  {
296    /***** CLEANUP PROCESS *****/
297    /* terminate all networking connections */
298    enet_host_destroy( this->server );
299
300    /* free all used memory */
301    /* clear the list of connected game servers */
302    /* clear the list of connected game clients */
303
304  }
305
306/* end of namespace */
307}
Note: See TracBrowser for help on using the repository browser.