stk-code_catmod/src/network_manager.cpp

232 lines
7.5 KiB
C++
Raw Normal View History

// $Id: network_manager.hpp 2128 2008-06-13 00:53:52Z cosmosninja $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs, Stephen Leak
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "network_manager.hpp"
#include "stk_config.hpp"
NetworkManager* network_manager = 0;
NetworkManager::NetworkManager()
{
m_mode = NW_NONE;
m_state = NS_SYNCHRONISING;
m_port = 12345;
m_server_address = "172.31.41.53";
m_num_clients = 0;
#ifdef HAVE_ENET
if (enet_initialize () != 0)
{
fprintf (stderr, "An error occurred while initializing ENet.\n");
exit(-1);
}
#endif
} // NetworkManager
// -----------------------------------------------------------------------------
bool NetworkManager::initialiseConnections()
{
switch(m_mode)
{
case NW_NONE: return true;
case NW_CLIENT: return initClient();
case NW_SERVER: return initServer();
}
return true;
} // NetworkManager
// -----------------------------------------------------------------------------
NetworkManager::~NetworkManager()
{
#ifdef HAVE_ENET
if(m_mode==NW_SERVER || m_mode==NW_CLIENT) enet_host_destroy(m_host);
enet_deinitialize();
#endif
} // ~NetworkManager
// -----------------------------------------------------------------------------
bool NetworkManager::initServer()
{
#ifdef HAVE_ENET
fprintf(stderr, "Initialising server, listening on %d\n", m_port);
ENetAddress address;
address.host = ENET_HOST_ANY;
address.port = m_port;
m_host = enet_host_create (& address /* the address to bind the server host to */,
stk_config->m_max_karts /* number of connections */,
0 /* incoming bandwidth */,
0 /* outgoing bandwidth */ );
if (m_host == NULL)
{
fprintf (stderr,
"An error occurred while trying to create an ENet server host.\n"
"Progressing in non-network mode\n");
m_mode = NW_NONE;
return false;
}
fprintf(stderr, "Server initialised, waiting for connections ...\n");
return true;
#endif
} // initServer
// -----------------------------------------------------------------------------
bool NetworkManager::initClient()
{
fprintf(stderr, "Initialising client\n");
#ifdef HAVE_ENET
m_host = enet_host_create (NULL /* create a client host */,
1 /* only allow 1 outgoing connection */,
0 /* downstream bandwidth unlimited */,
0 /* upstream bandwidth unlimited */ );
if (m_host == NULL)
{
fprintf (stderr,
"An error occurred while trying to create an ENet client host.\n");
return false;
}
ENetAddress address;
ENetEvent event;
ENetPeer *peer;
enet_address_set_host (& address, m_server_address.c_str());
address.port = m_port;
/* Initiate the connection, allocating the two channels 0 and 1. */
peer = enet_host_connect (m_host, &address, 2);
if (peer == NULL)
{
fprintf (stderr,
"No available peers for initiating an ENet connection.\n");
return false;
}
/* Wait up to 5 seconds for the connection attempt to succeed. */
if (enet_host_service (m_host, & event, 5000) > 0 &&
event.type == ENET_EVENT_TYPE_CONNECT)
{
fprintf(stderr, "Connection to %s:%d succeeded.",
m_server_address.c_str(), m_port);
enet_host_service(m_host, &event, 1000);
}
else
{
/* Either the 5 seconds are up or a disconnect event was */
/* received. Reset the peer in the event the 5 seconds */
/* had run out without any significant event. */
enet_peer_reset (peer);
fprintf(stderr, "Connection to '%s:%d' failed.",
m_server_address.c_str(), m_port);
}
return true;
#endif
} // initServer
// ----------------------------------------------------------------------------
void NetworkManager::handleNewConnection(ENetEvent *event)
{
if(m_state!=NS_SYNCHRONISING)
{
// We don't accept connections atm
return;
}
m_num_clients++;
fprintf (stderr, "A new client connected from %x:%u. Connected: %d.\n",
event->peer -> address.host,
event->peer -> address.port, m_num_clients);
} // handleNewConnection
// ----------------------------------------------------------------------------
void NetworkManager::handleDisconnection(ENetEvent *event)
{
if(m_state!=NS_SYNCHRONISING)
{
fprintf(stderr, "Disconnect while in race - close your eyes and hope for the best.\n");
return;
}
fprintf(stderr, "%x:%d disconected.\n", event->peer->address.host,
event->peer->address.port );
m_num_clients--;
} // handleDisconnection
// ----------------------------------------------------------------------------
void NetworkManager::handleNewMessage(ENetEvent *event)
{
if(m_state==NS_SYNCHRONISING)
{
fprintf(stderr, "Received a receive event while waiting for client - ignored.\n");
return;
}
} // handleNewMessage
// ----------------------------------------------------------------------------
void NetworkManager::update(float dt)
{
ENetEvent event;
int result = enet_host_service (m_host, &event, 1);
if(result==0) return;
if(result<0)
{
fprintf(stderr, "Error while receiving messages -> ignored.\n");
return;
}
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT: handleNewConnection(&event); break;
case ENET_EVENT_TYPE_RECEIVE: handleNewMessage(&event); break;
case ENET_EVENT_TYPE_DISCONNECT: handleDisconnection(&event); break;
case ENET_EVENT_TYPE_NONE: break;
}
} // update
// ----------------------------------------------------------------------------
/** Send race_manager->getNumPlayers(), the kart and the name of each
player to the server.
*/
void NetworkManager::sendKartsInformationToServer()
{
} // sendKartsInformationToServer
// ----------------------------------------------------------------------------
/** Receive and store the information from sendKartsInformation()
*/
void NetworkManager::waitForKartsInformation()
{
} // waitForKartsInformation
// ----------------------------------------------------------------------------
/** Sends the information from the race_manager to all clients.
*/
void NetworkManager::sendRaceInformationToClients()
{
} // sendRaceInformationToClients
// ----------------------------------------------------------------------------
/** Receives and sets the race_manager information.
*/
void NetworkManager::waitForRaceInformation()
{
} // waitForRaceInformation
// ----------------------------------------------------------------------------