Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

fatal bug found.

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