1) Added missing files from previous commit.
2) Added kart_packet classes. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2234 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -121,6 +121,7 @@ supertuxkart_SOURCES = main.cpp \
|
||||
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/network_gui.cpp gui/network_gui.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 \
|
||||
|
||||
254
src/gui/network_gui.cpp
Normal file
254
src/gui/network_gui.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
// $Id: network_gui.cpp 2148 2008-07-03 03:14:27Z hikerstk $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
//
|
||||
// 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 <sstream>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "widget_manager.hpp"
|
||||
#include "network_gui.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "menu_manager.hpp"
|
||||
#include "translation.hpp"
|
||||
#include "sdldrv.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "user_config.hpp"
|
||||
|
||||
enum WidgetTokens
|
||||
{
|
||||
WTOK_TITLE,
|
||||
WTOK_CONNECT,
|
||||
WTOK_SERVER,
|
||||
WTOK_SERVER_ADDRESS,
|
||||
WTOK_CONNECTED,
|
||||
WTOK_QUIT
|
||||
};
|
||||
|
||||
/** Limits the maximum length of the player name. */
|
||||
const int NetworkGUI::SERVER_NAME_MAX = 50;
|
||||
|
||||
|
||||
NetworkGUI::NetworkGUI()
|
||||
{
|
||||
|
||||
Widget *w=widget_manager->addTitleWgt( WTOK_TITLE, 60, 7, _("Select network mode"));
|
||||
w->setPosition(WGT_DIR_CENTER, 0.0, WGT_DIR_FROM_TOP, 0.1f);
|
||||
|
||||
Widget *w_prev=widget_manager->addTextButtonWgt( WTOK_CONNECT, 30, 7, _("Connect to server:") );
|
||||
w_prev->setPosition(WGT_DIR_FROM_LEFT, 0.05f, WGT_DIR_FROM_TOP, 0.2f);
|
||||
|
||||
w=widget_manager->addTextButtonWgt( WTOK_SERVER, 30, 7, _("Become server") );
|
||||
w->setPosition(WGT_DIR_FROM_LEFT, 0.05f, NULL,
|
||||
WGT_DIR_UNDER_WIDGET, 0, w_prev);
|
||||
widget_manager->sameWidth(WTOK_CONNECT, WTOK_SERVER);
|
||||
|
||||
std::ostringstream s;
|
||||
s<<user_config->m_server_address<<":"<<user_config->m_server_port;
|
||||
m_server_address=s.str();
|
||||
w=widget_manager->addTextButtonWgt(WTOK_SERVER_ADDRESS, 50, 7, m_server_address);
|
||||
w->setPosition(WGT_DIR_RIGHT_WIDGET, 0.05f, w_prev,
|
||||
WGT_DIR_FROM_TOP, 0.2f, NULL);
|
||||
|
||||
w=widget_manager->addTextButtonWgt(WTOK_CONNECTED, 50, 20, " ");
|
||||
w->setPosition(WGT_DIR_RIGHT_WIDGET, 0.05f, w_prev,
|
||||
WGT_DIR_FROM_TOP, 0.2f, NULL);
|
||||
widget_manager->hideWgt(WTOK_CONNECTED);
|
||||
widget_manager->deactivateWgt(WTOK_CONNECTED);
|
||||
|
||||
w=widget_manager->addTextButtonWgt( WTOK_QUIT, 60, 7, _("Press <ESC> to go back") );
|
||||
w->setPosition(WGT_DIR_CENTER, 0, WGT_DIR_FROM_BOTTOM, 0);
|
||||
|
||||
// This can happen either when going back here, or when a command line
|
||||
// option was specified causing the connection to already have happened
|
||||
if(network_manager->getMode()==NetworkManager::NW_SERVER)
|
||||
switchToWaitForConnectionMode();
|
||||
widget_manager->layout(WGT_AREA_ALL);
|
||||
} // NetworkGUI
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
NetworkGUI::~NetworkGUI()
|
||||
{
|
||||
widget_manager->reset();
|
||||
} // ~NetworkGUI
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetworkGUI::select()
|
||||
{
|
||||
const int selected = widget_manager->getSelectedWgt();
|
||||
switch (selected)
|
||||
{
|
||||
case WTOK_SERVER_ADDRESS:
|
||||
// Switch to typing in the address of the server
|
||||
widget_manager->setWgtText(WTOK_SERVER_ADDRESS, (m_server_address + "<").c_str());
|
||||
|
||||
inputDriver->setMode(LOWLEVEL);
|
||||
|
||||
break;
|
||||
case WTOK_CONNECT:
|
||||
network_manager->setMode(NetworkManager::NW_CLIENT);
|
||||
if(!network_manager->initialiseConnections())
|
||||
{
|
||||
fprintf(stderr, "Problems initialising network connections,\n"
|
||||
"Running in non-network mode.\n");
|
||||
}
|
||||
break;
|
||||
case WTOK_SERVER:
|
||||
network_manager->setMode(NetworkManager::NW_SERVER);
|
||||
if(!network_manager->initialiseConnections())
|
||||
{
|
||||
fprintf(stderr, "Problems initialising network connections,\n"
|
||||
"Running in non-network mode.\n");
|
||||
}
|
||||
switchToWaitForConnectionMode();
|
||||
break;
|
||||
case WTOK_QUIT:
|
||||
// Leave menu.
|
||||
menu_manager->popMenu();
|
||||
|
||||
break;
|
||||
}
|
||||
} // select
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetworkGUI::switchToWaitForConnectionMode()
|
||||
{
|
||||
widget_manager->setWgtText(WTOK_CONNECT, _("Connected:"));
|
||||
widget_manager->deactivateWgt(WTOK_CONNECT); //make it non-selectable
|
||||
widget_manager->setWgtText(WTOK_QUIT, _("OK"));
|
||||
widget_manager->hideWgt(WTOK_SERVER_ADDRESS);
|
||||
widget_manager->showWgt(WTOK_CONNECTED);
|
||||
widget_manager->hideWgt(WTOK_SERVER);
|
||||
widget_manager->setWgtText(WTOK_TITLE,_("Waiting for clients"));
|
||||
m_num_clients = 0;
|
||||
} // switchToWaitForConnectionMode
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetworkGUI::update(float dt)
|
||||
{
|
||||
widget_manager->update(0.0f);
|
||||
if(m_num_clients==network_manager->getNumClients()) return;
|
||||
|
||||
// At least one new client has connected:
|
||||
std::string s="";
|
||||
m_num_clients = network_manager->getNumClients();
|
||||
for(unsigned int i=1; i<=m_num_clients; i++)
|
||||
{
|
||||
s+=network_manager->getClientName(i)+"\n";
|
||||
}
|
||||
widget_manager->setWgtText(WTOK_CONNECTED, s);
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetworkGUI::inputKeyboard(SDLKey key, int unicode)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case SDLK_RSHIFT:
|
||||
case SDLK_LSHIFT:
|
||||
// Ignore shift, otherwise shift will disable input
|
||||
// (making it impossible to enter upper case characters)
|
||||
case SDLK_SPACE:
|
||||
// Ignore space to prevent invisible names.
|
||||
|
||||
// Note: This will never happen as long as SPACE has a mapping which
|
||||
// causes GA_ENTER and therefore finishes the typing. Please leave this
|
||||
// because I am not sure whether this is good behavior (that SPACE
|
||||
// cannot reach inputKeyboard()) and with some changes to the input
|
||||
// driver this code has suddenly a useful effect.
|
||||
case SDLK_KP_ENTER:
|
||||
case SDLK_RETURN:
|
||||
case SDLK_ESCAPE:
|
||||
// Ignore some control keys. What they could provide is implemented
|
||||
// in the handle() method.
|
||||
return;
|
||||
case SDLK_BACKSPACE:
|
||||
// Handle backspace.
|
||||
if (m_server_address.size() >=1)
|
||||
m_server_address.erase(m_server_address.size()-1, 1);
|
||||
|
||||
widget_manager->setWgtText(WTOK_SERVER_ADDRESS, (m_server_address + "<").c_str());
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
// Adds the character to the name.
|
||||
// For this menu only unicode translation is enabled.
|
||||
// So we use the unicode character here, since this will
|
||||
// take care of upper/lower case etc.
|
||||
if (unicode && m_server_address.size() <= SERVER_NAME_MAX)
|
||||
m_server_address += (char) unicode;
|
||||
widget_manager->setWgtText(WTOK_SERVER_ADDRESS, (m_server_address + "<").c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetworkGUI::handle(GameAction ga, int value)
|
||||
{
|
||||
if (value)
|
||||
return;
|
||||
|
||||
switch (ga)
|
||||
{
|
||||
case GA_ENTER:
|
||||
// If the user is typing her name this will be finished at this
|
||||
// point.
|
||||
if (inputDriver->isInMode(LOWLEVEL))
|
||||
{
|
||||
// Prevents zero-length names.
|
||||
if (m_server_address.length() == 0)
|
||||
m_server_address = "localhost:2305";
|
||||
std::vector<std::string> sl=StringUtils::split(m_server_address,':');
|
||||
if(sl.size()>1)
|
||||
{
|
||||
user_config->m_server_address = sl[0];
|
||||
user_config->m_server_port = atoi(sl[1].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
user_config->m_server_address = m_server_address;
|
||||
std::ostringstream s;
|
||||
s<<m_server_address<<":"<<user_config->m_server_port;
|
||||
m_server_address=s.str();
|
||||
}
|
||||
widget_manager->setWgtText(WTOK_SERVER_ADDRESS, m_server_address.c_str());
|
||||
|
||||
inputDriver->setMode(MENU);
|
||||
}
|
||||
else
|
||||
select();
|
||||
break;
|
||||
case GA_LEAVE:
|
||||
// If the user is typing her name this will be cancelled at this
|
||||
// point.
|
||||
if (inputDriver->isInMode(LOWLEVEL))
|
||||
{
|
||||
std::ostringstream s;
|
||||
s<<user_config->m_server_address<<":"<<user_config->m_server_port;
|
||||
m_server_address=s.str();
|
||||
widget_manager->setWgtText(WTOK_SERVER_ADDRESS, m_server_address.c_str());
|
||||
|
||||
inputDriver->setMode(MENU);
|
||||
break;
|
||||
}
|
||||
// Fall through to reach the usual GA_LEAVE code (leave menu).
|
||||
default:
|
||||
BaseGUI::handle(ga, value);
|
||||
}
|
||||
|
||||
}
|
||||
47
src/gui/network_gui.hpp
Normal file
47
src/gui/network_gui.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// $Id: network_gui.hpp 2128 2008-06-13 00:53:52Z cosmosninja $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef HEADER_NETWORK_GUI_H
|
||||
#define HEADER_NETWORK_GUI_H
|
||||
|
||||
#include <string>
|
||||
#include <SDL/SDL.h>
|
||||
#include "base_gui.hpp"
|
||||
#include "player.hpp"
|
||||
|
||||
class NetworkGUI: public BaseGUI
|
||||
{
|
||||
private:
|
||||
unsigned int m_num_clients;
|
||||
std::string m_server_address;
|
||||
|
||||
static const int SERVER_NAME_MAX;
|
||||
|
||||
void switchToWaitForConnectionMode();
|
||||
public:
|
||||
NetworkGUI();
|
||||
~NetworkGUI();
|
||||
void select();
|
||||
void update(float dt);
|
||||
void handle(GameAction, int);
|
||||
void inputKeyboard(SDLKey, int);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -85,6 +85,9 @@ bool NetworkManager::initServer()
|
||||
return false;
|
||||
}
|
||||
|
||||
m_server = NULL;
|
||||
m_clients.push_back(NULL); // server has host_id=0, so put a dummy entry at 0 in client array
|
||||
|
||||
fprintf(stderr, "Server initialised, waiting for connections ...\n");
|
||||
m_client_names.push_back("server");
|
||||
return true;
|
||||
@@ -140,17 +143,26 @@ bool NetworkManager::initClient()
|
||||
}
|
||||
fprintf(stderr, "Connection to %s:%d succeeded.\n",
|
||||
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;
|
||||
|
||||
return true;
|
||||
m_server = peer;
|
||||
if (enet_host_service(m_host, &event, 5000) > 0)
|
||||
if (event.type == ENET_EVENT_TYPE_RECEIVE)
|
||||
{
|
||||
m_host_id = ClientHostIdPacket(event.packet).getId();
|
||||
fprintf(stderr, "got host id %d from server\n", m_host_id);
|
||||
return true;
|
||||
}
|
||||
fprintf(stderr, "didn't receive a host_id!\n");
|
||||
return false;
|
||||
#endif
|
||||
} // initClient
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkManager::handleNewConnection(ENetEvent *event)
|
||||
{
|
||||
ClientHostIdPacket *msg;
|
||||
int new_host_id;
|
||||
|
||||
if(m_state!=NS_ACCEPT_CONNECTIONS)
|
||||
{
|
||||
// We don't accept connections atm
|
||||
@@ -164,6 +176,16 @@ void NetworkManager::handleNewConnection(ENetEvent *event)
|
||||
// FIXME: send m_num_clients as hostid back to new client.
|
||||
// FIXME: client should send an id as well to be displayed
|
||||
m_client_names.push_back("client");
|
||||
|
||||
// send a hostid back
|
||||
new_host_id = m_clients.size();
|
||||
// fprintf (stderr, "allocated client host_id as %d\n", new_host_id);
|
||||
m_clients.push_back(event->peer);
|
||||
msg = new ClientHostIdPacket(new_host_id);
|
||||
msg->send(*(m_clients[new_host_id]));
|
||||
enet_host_flush(m_host);
|
||||
delete msg;
|
||||
|
||||
} // handleNewConnection
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -181,7 +203,8 @@ void NetworkManager::handleDisconnection(ENetEvent *event)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkManager::handleServerMessage(ENetEvent *event)
|
||||
{
|
||||
{ // handle message at server (from client)
|
||||
|
||||
switch(m_state)
|
||||
{
|
||||
case NS_ACCEPT_CONNECTIONS:
|
||||
@@ -264,7 +287,7 @@ void NetworkManager::switchToRaceDataSynchronisation()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkManager::handleClientMessage(ENetEvent *event)
|
||||
{
|
||||
{ // handle message at client (from server)
|
||||
switch(m_state)
|
||||
{
|
||||
case NS_WAIT_FOR_RACE_DATA:
|
||||
@@ -307,10 +330,17 @@ void NetworkManager::update(float dt)
|
||||
*/
|
||||
void NetworkManager::sendKartsInformationToServer()
|
||||
{
|
||||
LocalKartInfoPacket *msg;
|
||||
for(int i=0; i<(int)race_manager->getNumLocalPlayers(); i++)
|
||||
{
|
||||
fprintf(stderr, "Sending name '%s', ",user_config->m_player[i].getName().c_str());
|
||||
fprintf(stderr, "kart name '%s'\n", race_manager->getLocalKartInfo(i).getKartName().c_str());
|
||||
msg = new LocalKartInfoPacket(user_config->m_player[i].getName(), /* player name */
|
||||
race_manager->getLocalKartInfo(i).getKartName()); /* kart name */
|
||||
msg->send(*m_server);
|
||||
enet_host_flush(m_host);
|
||||
delete msg;
|
||||
|
||||
} // for i<getNumLocalPlayers
|
||||
fprintf(stderr, "Client sending kart information to server\n");
|
||||
m_state = NS_WAIT_FOR_RACE_DATA;
|
||||
@@ -321,12 +351,23 @@ void NetworkManager::sendKartsInformationToServer()
|
||||
*/
|
||||
void NetworkManager::setupPlayerKartInfo()
|
||||
{
|
||||
LocalKartInfoPacket *msg;
|
||||
m_kart_info.clear();
|
||||
|
||||
// FIXME: debugging
|
||||
//m_kart_info.push_back(RemoteKartInfo(0, "tuxkart","xx", 1));
|
||||
//m_kart_info.push_back(RemoteKartInfo(1, "yetikart", "yy", 1));
|
||||
|
||||
// FIXME: put this into state machine
|
||||
//if (enet_host_service(m_host, &event, 15000) > 0)
|
||||
// if (event.type == ENET_EVENT_TYPE_RECEIVE)
|
||||
// {
|
||||
// msg = new LocalKartDetails(event.packet)
|
||||
// m_kart_info.push_back(RemoteKartInfo(0, "tuxkart","xx", 1));
|
||||
// m_kart_info.push_back(RemoteKartInfo(1, "yetikart", "yy", 1));
|
||||
// }
|
||||
//fprintf(stderr, "didn't receive kart info!\n");
|
||||
|
||||
// Get the local kart info
|
||||
for(unsigned int i=0; i<race_manager->getNumLocalPlayers(); i++)
|
||||
m_kart_info.push_back(race_manager->getLocalKartInfo(i));
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "network/remote_kart_info.hpp"
|
||||
#include "network/kart_packet.hpp"
|
||||
|
||||
#ifdef HAVE_ENET
|
||||
# include "enet/enet.h"
|
||||
@@ -53,7 +54,9 @@ private:
|
||||
std::vector<std::string> m_client_names;
|
||||
int m_barrier_count;
|
||||
#ifdef HAVE_ENET
|
||||
ENetHost *m_host;
|
||||
ENetHost *m_host; // me
|
||||
ENetPeer *m_server; // (clients only)
|
||||
std::vector<ENetPeer*> m_clients; // (server only) pos in vector is client host_id
|
||||
#endif
|
||||
|
||||
bool initServer();
|
||||
|
||||
Reference in New Issue
Block a user