Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/network/MasterServer.cc @ 8529

Last change on this file since 8529 was 8351, checked in by rgrieder, 14 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

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