Added network GUI, some improvements to network manager state,

server address and port are now saved in the user configuration.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2233 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2008-09-07 14:00:47 +00:00
parent fd93bfef1a
commit afbd02d824
19 changed files with 130 additions and 69 deletions

View File

@ -120,6 +120,7 @@ supertuxkart_SOURCES = main.cpp \
gui/race_options.cpp gui/race_options.hpp \
gui/char_sel.cpp gui/char_sel.hpp \
gui/start_race_feedback.cpp gui/start_race_feedback.hpp \
gui/network_info.cpp gui/network_info.hpp \
gui/main_menu.cpp gui/main_menu.hpp \
gui/help_page_one.cpp gui/help_page_one.hpp \
gui/help_page_two.cpp gui/help_page_two.hpp \

View File

@ -32,6 +32,7 @@ enum WidgetTokens
{
WTOK_SINGLE,
WTOK_MULTI,
WTOK_NETWORK,
WTOK_CHALLENGES,
WTOK_OPTIONS,
WTOK_QUIT,
@ -47,6 +48,11 @@ MainMenu::MainMenu()
const int WIDTH=30;
widget_manager->addTextButtonWgt( WTOK_SINGLE, WIDTH, 7, _("Single Player") );
widget_manager->addTextButtonWgt( WTOK_MULTI, WIDTH, 7, _("Multiplayer") );
#ifdef HAVE_ENET
// Only display the networking entry when not already connected.
if(network_manager->getMode()==NetworkManager::NW_NONE)
widget_manager->addTextButtonWgt( WTOK_NETWORK, WIDTH, 7, _("Networking") );
#endif
std::vector<const Challenge*> all_challenges=unlock_manager->getActiveChallenges();
// Only allow challenges if not networking for now!
@ -104,6 +110,9 @@ void MainMenu::select()
case WTOK_MULTI:
menu_manager->pushMenu(MENUID_NUMPLAYERS);
break;
case WTOK_NETWORK:
menu_manager->pushMenu(MENUID_NETWORK_GUI);
break;
case WTOK_CHALLENGES:
menu_manager->pushMenu(MENUID_CHALLENGES);
break;

View File

@ -55,6 +55,7 @@
#include "feature_unlocked.hpp"
#include "start_race_feedback.hpp"
#include "network_info.hpp"
#include "network_gui.hpp"
using namespace std;
@ -240,6 +241,9 @@ void MenuManager::update()
case MENUID_START_RACE_FEEDBACK:
m_current_menu = new StartRaceFeedback();
break;
case MENUID_NETWORK_GUI:
m_current_menu = new NetworkGUI();
break;
case MENUID_NETWORK_INFO:
m_current_menu = new NetworkInfo();
break;

View File

@ -45,6 +45,7 @@ enum MenuManagerIDs
MENUID_GRANDPRIXSELECT,
MENUID_UNLOCKED_FEATURE,
MENUID_START_RACE_FEEDBACK, // 'loading'
MENUID_NETWORK_GUI,
MENUID_NETWORK_INFO, // wait for clients to connect
// menu configuration

View File

@ -33,7 +33,6 @@ enum WidgetTokens
NetworkInfo::NetworkInfo()
{
//Add some feedback so people know they are going to start the race
widget_manager->reset();
Widget *w_prev=widget_manager->addTitleWgt( WTOK_MSG, 60, 7, _("Waiting for clients ...") );
w_prev->setPosition(WGT_DIR_CENTER, 0.0, NULL,

View File

@ -56,13 +56,9 @@ enum WidgetTokens
RaceOptions::RaceOptions()
{
// First update the server's race_manager with the number of players
if(network_manager->getMode()==NetworkManager::NW_CLIENT)
if(network_manager->getMode()==NetworkManager::NW_SERVER)
{
network_manager->sendKartsInformationToServer();
}
else if(network_manager->getMode()==NetworkManager::NW_SERVER)
{
network_manager->waitForKartsInformation();
network_manager->switchToReceiveKartInfo(); // NS_WAIT_FOR_KART_INFO
}
m_difficulty=race_manager->getDifficulty();
@ -146,6 +142,8 @@ RaceOptions::RaceOptions()
widget_manager->setWgtBorderPercentage( WTOK_START, 20 );
widget_manager->setWgtBorderColor( WTOK_START, WGT_TRANS_BLUE );
widget_manager->showWgtBorder( WTOK_START );
// Disable till all messages from the clients have arrived
widget_manager->deactivateWgt(WTOK_START);
widget_manager->breakLine();
widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 1, 10);
@ -163,6 +161,15 @@ RaceOptions::~RaceOptions()
widget_manager->reset();
} // ~RaceOptions
//-----------------------------------------------------------------------------
void RaceOptions::update(float dt)
{
if(network_manager->getState()!=NetworkManager::NS_WAIT_FOR_KART_INFO)
{
widget_manager->activateWgt(WTOK_START);
}
BaseGUI::update(dt);
} // update
//-----------------------------------------------------------------------------
void RaceOptions::select()
{
@ -283,11 +290,7 @@ void RaceOptions::select()
menu_manager->pushMenu(MENUID_START_RACE_FEEDBACK);
if(network_manager->getMode()==NetworkManager::NW_SERVER)
{
network_manager->sendRaceInformationToClients();
}
else if(network_manager->getMode()==NetworkManager::NW_CLIENT)
{
network_manager->waitForRaceInformation();
network_manager->sendRaceInformationToClients(); // NS_READY_SET_GO_BARRIER
}
break;
case WTOK_QUIT:

View File

@ -33,6 +33,7 @@ public:
~RaceOptions();
void select();
void update(float dt);
};
#endif

View File

@ -30,13 +30,11 @@ enum WidgetTokens
StartRaceFeedback::StartRaceFeedback()
{
network_manager->switchToRaceDataSynchronisation();
m_state = network_manager->getMode()==NetworkManager::NW_NONE ? SRF_LOADING : SRF_NETWORK;
m_state = SRF_NETWORK;
//Add some feedback so people know they are going to start the race
widget_manager->reset();
if(m_state==SRF_NETWORK)
if(network_manager->getMode()!=NetworkManager::NW_NONE)
widget_manager->addTextWgt( WTOK_MSG, 60, 7, _("Synchronising network...") );
else
widget_manager->addTextWgt( WTOK_MSG, 60, 7, _("Loading race...") );
@ -68,15 +66,17 @@ void StartRaceFeedback::update(float DELTA)
break;
case SRF_NETWORK:
// The server only waits for one frame:
if(network_manager->getMode()==NetworkManager::NW_SERVER)
if(network_manager->getMode()!=NetworkManager::NW_CLIENT)
{
// Server or stand alone:
network_manager->sendRaceInformationToClients();
network_manager->setupPlayerKartInfo();
m_state = SRF_LOADING_DISPLAY;
widget_manager->setWgtText(WTOK_MSG, _("Loading race...") );
return;
}
// The client have to be busy waiting till the race data has arrived:
if(network_manager->getState()==NetworkManager::NS_WAITING_FOR_RACE_DATA)
if(network_manager->getState()==NetworkManager::NS_WAIT_FOR_RACE_DATA)
return;
m_state = SRF_LOADING_DISPLAY;
widget_manager->setWgtText(WTOK_MSG, _("Loading race...") );

View File

@ -1006,6 +1006,10 @@
RelativePath="../../../src\gui\menu_manager.cpp"
>
</File>
<File
RelativePath="..\..\gui\network_gui.cpp"
>
</File>
<File
RelativePath="..\..\gui\network_info.cpp"
>
@ -1484,6 +1488,10 @@
RelativePath="../../../src\gui\menu_manager.hpp"
>
</File>
<File
RelativePath="..\..\gui\network_gui.hpp"
>
</File>
<File
RelativePath="..\..\gui\network_info.hpp"
>

View File

@ -163,7 +163,7 @@ int handleCmdLine(int argc, char **argv)
else if(sscanf(argv[i], "--server=%d",&n)==1)
{
network_manager->setMode(NetworkManager::NW_SERVER);
network_manager->setPort(n);
user_config->m_server_port = n;
}
else if( !strcmp(argv[i], "--server") )
{
@ -171,12 +171,12 @@ int handleCmdLine(int argc, char **argv)
}
else if( sscanf(argv[i], "--port=%d", &n) )
{
network_manager->setPort(n);
user_config->m_server_port=n;
}
else if( sscanf(argv[i], "--client=%s", s) )
{
network_manager->setMode(NetworkManager::NW_CLIENT);
network_manager->setServerIP(s);
user_config->m_server_address=s;
}
#endif
else if( (!strcmp(argv[i], "--kart") && i+1<argc ))
@ -531,15 +531,18 @@ int main(int argc, char *argv[] )
exit(-3);
}
// Initialise connection in case that a command line option was set
// configuring a client or server. Otherwise this function does nothing
// here (and will be called again from the network gui).
if(!network_manager->initialiseConnections())
{
fprintf(stderr, "Problems initialising network connections,\n"
"Running in non-network mode.\n");
}
// On the server start with the network information page
// On the server start with the network information page for now
if(network_manager->getMode()==NetworkManager::NW_SERVER)
{
menu_manager->pushMenu(MENUID_NETWORK_INFO);
menu_manager->pushMenu(MENUID_NETWORK_GUI);
}
// Not replaying
// =============

View File

@ -18,8 +18,12 @@
// 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_kart.hpp"
#include "network/network_manager.hpp"
#include "network/network_kart.hpp"
/** A network kart. On the server, it receives its control information (steering etc)
from the network manager.
*/
NetworkKart::NetworkKart(const std::string &kart_name, int position,
const btTransform &init_transform, int global_player_id)
: Kart(kart_name, position, init_transform)
@ -28,3 +32,10 @@ NetworkKart::NetworkKart(const std::string &kart_name, int position,
} // NetworkKart
// ----------------------------------------------------------------------------
void NetworkKart::setControl(const KartControl& kc)
{
assert(network_manager->getMode()==NetworkManager::NW_SERVER);
m_controls = kc;
} // setControl
// ----------------------------------------------------------------------------

View File

@ -27,9 +27,9 @@ class NetworkKart : public Kart
private:
int m_global_player_id; // to identify this kart to the network manager
public:
NetworkKart(const std::string& kart_name, int position,
const btTransform& init_transform,
int global_player_id);
NetworkKart(const std::string& kart_name, int position,
const btTransform& init_transform,
int global_player_id);
void setControl(const KartControl& kc);
}; // NetworkKart
#endif

View File

@ -29,8 +29,7 @@ NetworkManager::NetworkManager()
{
m_mode = NW_NONE;
m_state = NS_ACCEPT_CONNECTIONS;
m_port = 12345;
m_server_address = "172.31.41.53";
m_num_clients = 0;
m_host_id = 0;
#ifdef HAVE_ENET
@ -67,11 +66,11 @@ NetworkManager::~NetworkManager()
bool NetworkManager::initServer()
{
#ifdef HAVE_ENET
fprintf(stderr, "Initialising server, listening on %d\n", m_port);
fprintf(stderr, "Initialising server, listening on %d\n", user_config->m_server_port);
ENetAddress address;
address.host = ENET_HOST_ANY;
address.port = m_port;
address.port = user_config->m_server_port;
m_host = enet_host_create (& address /* the address to bind the server host to */,
stk_config->m_max_karts /* number of connections */,
@ -113,8 +112,8 @@ bool NetworkManager::initClient()
ENetEvent event;
ENetPeer *peer;
enet_address_set_host (& address, m_server_address.c_str());
address.port = m_port;
enet_address_set_host (& address, user_config->m_server_address.c_str());
address.port = user_config->m_server_port;
/* Initiate the connection, allocating the two channels 0 and 1. */
peer = enet_host_connect (m_host, &address, 2);
@ -136,11 +135,11 @@ bool NetworkManager::initClient()
enet_peer_reset (peer);
fprintf(stderr, "Connection to '%s:%d' failed.\n",
m_server_address.c_str(), m_port);
user_config->m_server_address.c_str(), user_config->m_server_port);
return false;
}
fprintf(stderr, "Connection to %s:%d succeeded.\n",
m_server_address.c_str(), m_port);
user_config->m_server_address.c_str(), user_config->m_server_port);
enet_host_service(m_host, &event, 1000);
// FIXME Receive host id from server here!!
m_host_id = 1;
@ -213,12 +212,13 @@ void NetworkManager::handleServerMessage(ENetEvent *event)
m_state = NS_RACING;
}
break;
case NS_KART_INFO_BARRIER:
case NS_WAIT_FOR_KART_INFO:
m_barrier_count++;
// handle message, i.e. append to m_kart_info
if(m_barrier_count==m_num_clients)
{
// broadcast start message
m_state = NS_RACING;
m_state = NS_READY_SET_GO_BARRIER;
}
break;
@ -228,9 +228,15 @@ void NetworkManager::handleServerMessage(ENetEvent *event)
// ----------------------------------------------------------------------------
void NetworkManager::switchToReadySetGoBarrier()
{
assert(m_state == NS_CHARACTER_SELECT);
m_state = NS_READY_SET_GO_BARRIER;
m_barrier_count = 0;
if(m_num_clients==0)
{
m_state = NS_RACING;
}
else
{
m_state = NS_READY_SET_GO_BARRIER;
m_barrier_count = 0;
}
} // switchToReadySetGoBarrier
// ----------------------------------------------------------------------------
@ -243,10 +249,16 @@ void NetworkManager::switchToCharacterSelection()
} // switchTocharacterSelection
// ----------------------------------------------------------------------------
void NetworkManager::switchToRaceDataSynchronisation()
void NetworkManager::switchToReceiveKartInfo()
{
assert(m_state == NS_CHARACTER_SELECT);
m_state = NS_KART_INFO_BARRIER;
m_state = NS_WAIT_FOR_KART_INFO;
} // switchToReceiveKartInfo
// ----------------------------------------------------------------------------
void NetworkManager::switchToRaceDataSynchronisation()
{
m_state = NS_WAIT_FOR_RACE_DATA;
m_barrier_count = 0;
} // switchToRaceDataSynchronisation
@ -255,10 +267,10 @@ void NetworkManager::handleClientMessage(ENetEvent *event)
{
switch(m_state)
{
case NS_ACCEPT_CONNECTIONS:
fprintf(stderr, "Received a receive event while waiting for client - ignored.\n");
return;
case NS_WAIT_FOR_RACE_DATA:
// check if message is really race data
fprintf(stderr, "Client received race data\n");
break;
} // switch m_state
} // handleClientMessage
@ -301,19 +313,19 @@ void NetworkManager::sendKartsInformationToServer()
fprintf(stderr, "kart name '%s'\n", race_manager->getLocalKartInfo(i).getKartName().c_str());
} // for i<getNumLocalPlayers
fprintf(stderr, "Client sending kart information to server\n");
m_state = NS_WAIT_FOR_RACE_DATA;
} // sendKartsInformationToServer
// ----------------------------------------------------------------------------
/** Receive and store the information from sendKartsInformation()
*/
void NetworkManager::waitForKartsInformation()
void NetworkManager::setupPlayerKartInfo()
{
m_kart_info.clear();
fprintf(stderr, "Server receiving all kart information\n");
// FIXME: debugging
m_kart_info.push_back(RemoteKartInfo(0, "tuxkart","xx", 1));
m_kart_info.push_back(RemoteKartInfo(1, "yetikart", "yy", 1));
//m_kart_info.push_back(RemoteKartInfo(0, "tuxkart","xx", 1));
//m_kart_info.push_back(RemoteKartInfo(1, "yetikart", "yy", 1));
// Get the local kart info
for(unsigned int i=0; i<race_manager->getNumLocalPlayers(); i++)
@ -334,7 +346,7 @@ void NetworkManager::waitForKartsInformation()
{
race_manager->setPlayerKart(i, m_kart_info[i]);
}
} // waitForKartsInformation
} // setupPlayerKartInfo
// ----------------------------------------------------------------------------
/** Sends the information from the race_manager to all clients.
@ -348,6 +360,9 @@ void NetworkManager::sendRaceInformationToClients()
fprintf(stderr, "Sending kart '%s' playerid %d host %d\n",
ki.getKartName().c_str(), ki.getLocalPlayerId(), ki.getHostId());
} // for i
// Go
m_state=NS_READY_SET_GO_BARRIER;
} // sendRaceInformationToClients
// ----------------------------------------------------------------------------

View File

@ -36,19 +36,17 @@ public:
enum NetworkMode {NW_SERVER, NW_CLIENT, NW_NONE};
// States for the finite state machine. First for server:
enum NetworkState {NS_ACCEPT_CONNECTIONS, NS_KART_INFO_BARRIER,
enum NetworkState {NS_ACCEPT_CONNECTIONS, NS_WAIT_FOR_KART_INFO,
// Then client only states:
NS_CHARACTER_CONFIRMED,
NS_CHARACTER_REJECTED,
NS_WAITING_FOR_RACE_DATA,
NS_WAIT_FOR_RACE_DATA,
// Shared states
NS_CHARACTER_SELECT, NS_READY_SET_GO_BARRIER, NS_RACING};
private:
NetworkMode m_mode;
NetworkState m_state;
int m_port;
std::string m_server_address;
int m_num_clients;
std::vector<RemoteKartInfo> m_kart_info;
int m_host_id;
@ -77,19 +75,19 @@ public:
unsigned int getNumClients() const {return m_num_clients; }
const std::string&
getClientName(int i) const {return m_client_names[i];}
void setPort(int p) {m_port=p; }
void setServerIP(const std::string &s) {m_server_address=s; }
void setKartInfo(int player_id, const std::string& kart,
const std::string& user="", int hostid=-1);
bool initialiseConnections();
void update(float dt);
void sendKartsInformationToServer();
void waitForKartsInformation();
void setupPlayerKartInfo();
void sendRaceInformationToClients();
void waitForRaceInformation();
void switchToReadySetGoBarrier();
void switchToCharacterSelection();
void switchToReceiveKartInfo();
void switchToRaceDataSynchronisation();
void switchToReadySetGoBarrier();
};

View File

@ -121,6 +121,8 @@ void UserConfig::setDefaults()
m_log_errors = false;
m_kart_group = "standard";
m_track_group = "standard";
m_server_address = "localhost";
m_server_port = 2305;
if(getenv("USERNAME")!=NULL) // for windows
m_username=getenv("USERNAME");
@ -444,9 +446,13 @@ void UserConfig::loadConfig(const std::string& filename)
lisp->get("log-errors", m_log_errors);
lisp->get("kart-group", m_kart_group);
lisp->get("track-group", m_track_group);
// Handle loading the stick config in it own method.
// Handle loading the stick config in it own method.
readStickConfigs(lisp);
// Address of server
lisp->get("server-address", m_server_address);
lisp->get("server-port", m_server_port);
// Unlock information:
const lisp::Lisp* unlock_info = lisp->getLisp("unlock-info");
if(unlock_info) unlock_manager->load(unlock_info);
@ -691,6 +697,10 @@ void UserConfig::saveConfig(const std::string& filename)
writer->write("kart-group", m_kart_group);
writer->writeComment("Last selected track group");
writer->write("track-group", m_track_group);
writer->writeComment("Information about last server used");
writer->write("server-address", m_server_address);
writer->write("server-port", m_server_port);
writeStickConfigs(writer);
// Write unlock information back

View File

@ -178,6 +178,8 @@ public:
std::string m_background_music;
std::string m_kart_group; // Kart group used last
std::string m_track_group; // Track group used last
std::string m_server_address;
int m_server_port;
bool m_replay_history;
bool m_use_kph;
int m_width;

View File

@ -811,13 +811,6 @@ void Widget::draw()
if(m_enable_text)
{
if(m_text.empty())
{
std::cerr << "Warning: widget tried to print an empty string.\n";
std::cerr << "(Did you set the text?)\n";
}
//For multilines we have to do a *very* ugly workaround for a plib
//bug which causes multiline strings to move to the left, at least
//while centering, and also gives wrong values for the size of the

View File

@ -298,6 +298,9 @@ public:
//size).
void setWgtCornerRadius(const int TOKEN, const int RADIUS);
void showWgtRect(const int TOKEN);
// Completely hide and show a widget
void hideWgt(const int t) {hideWgtRect(t); hideWgtText(t);}
void showWgt(const int t) {showWgtRect(t); showWgtText(t);}
void hideWgtRect(const int TOKEN);
void setWgtBorderColor(const int TOKEN, const GLfloat* const COLOR);

View File

@ -306,7 +306,7 @@ void World::update(float dt)
menu_manager->pushMenu(MENUID_RACERESULT);
}
if(!user_config->m_replay_history) history->StoreDelta(dt);
m_physics->update(dt);
if(network_manager->getMode()!=NetworkManager::NW_CLIENT) m_physics->update(dt);
for (int i = 0 ; i <(int) m_kart.size(); ++i)
{
// Update all karts that are not eliminated