Skip to content

Commit

Permalink
don't bind a UDP socket for local games (allows multiple local instan…
Browse files Browse the repository at this point in the history
…ces again sans hassle)
  • Loading branch information
kloot committed Oct 29, 2010
1 parent fd13290 commit 7071a29
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 36 deletions.
14 changes: 8 additions & 6 deletions rts/Game/GameServer.cpp
Expand Up @@ -101,9 +101,9 @@ void SetBoolArg(bool& value, const std::string& str)
}


CGameServer* gameServer=0;
CGameServer* gameServer = 0;

CGameServer::CGameServer(int hostport, bool onlyLocal, const GameData* const newGameData, const CGameSetup* const mysetup)
CGameServer::CGameServer(int hostport, const GameData* const newGameData, const CGameSetup* const mysetup)
: setup(mysetup)
{
assert(setup);
Expand Down Expand Up @@ -146,14 +146,16 @@ CGameServer::CGameServer(int hostport, bool onlyLocal, const GameData* const new
allowAdditionalPlayers = configHandler->Get("AllowAdditionalPlayers", false);
whiteListAdditionalPlayers = configHandler->Get("WhiteListAdditionalPlayers", true);

if (!onlyLocal)
if (!setup->onlyLocal) {
UDPNet.reset(new netcode::UDPListener(hostport));
}

std::string autohostip = configHandler->Get("AutohostIP", std::string("localhost"));
int autohostport = configHandler->Get("AutohostPort", 0);
const std::string& autohostip = configHandler->Get("AutohostIP", std::string("localhost"));
const int autohostport = configHandler->Get("AutohostPort", 0);

if (autohostport > 0)
if (autohostport > 0) {
AddAutohostInterface(autohostip, autohostport);
}

rng.Seed(newGameData->GetSetup().length());
Message(str(format(ServerStart) %hostport), false);
Expand Down
2 changes: 1 addition & 1 deletion rts/Game/GameServer.h
Expand Up @@ -61,7 +61,7 @@ class CGameServer
{
friend class CCregLoadSaveHandler; //For initialize server state after load
public:
CGameServer(int hostport, bool onlyLocal, const GameData* const gameData, const CGameSetup* const setup);
CGameServer(int hostport, const GameData* const gameData, const CGameSetup* const setup);
~CGameServer();

void AddLocalClient(const std::string& myName, const std::string& myVersion);
Expand Down
4 changes: 3 additions & 1 deletion rts/Game/GameSetup.cpp
Expand Up @@ -36,6 +36,7 @@ CGameSetup::CGameSetup()
, disableMapDamage(false)
, maxSpeed(0.0f)
, minSpeed(0.0f)
, onlyLocal(false)
, hostDemo(false)
, numDemoPlayers(0)
, gameStartDelay(0)
Expand Down Expand Up @@ -380,7 +381,7 @@ bool CGameSetup::Init(const std::string& buf)
// Parse
TdfParser file(buf.c_str(),buf.size());

if(!file.SectionExist("GAME"))
if (!file.SectionExist("GAME"))
return false;

// Game parameters
Expand All @@ -397,6 +398,7 @@ bool CGameSetup::Init(const std::string& buf)

file.GetTDef(gameStartDelay, (unsigned int) 4, "GAME\\GameStartDelay");

file.GetDef(onlyLocal, "0", "GAME\\OnlyLocal");
file.GetDef(useLuaGaia, "1", "GAME\\ModOptions\\LuaGaia");
file.GetDef(noHelperAIs, "0", "GAME\\ModOptions\\NoHelperAIs");
file.GetDef(maxUnits, "1500", "GAME\\ModOptions\\MaxUnits");
Expand Down
3 changes: 3 additions & 0 deletions rts/Game/GameSetup.h
Expand Up @@ -76,6 +76,9 @@ class CGameSetup
float maxSpeed;
float minSpeed;

/** if true, this is a non-network game (one local client, eg. when watching a demo) */
bool onlyLocal;

bool hostDemo;
std::string demoName;
int numDemoPlayers;
Expand Down
11 changes: 7 additions & 4 deletions rts/Game/PreGame.cpp
Expand Up @@ -184,14 +184,14 @@ void CPreGame::StartServer(const std::string& setupscript)
// (Which is OK, since unitsync does not have map options available either.)
setup->LoadStartPositions();

const std::string modArchive = archiveScanner->ArchiveFromName(setup->modName);
const std::string& modArchive = archiveScanner->ArchiveFromName(setup->modName);
const std::string& mapArchive = archiveScanner->ArchiveFromName(setup->mapName);
startupData->SetModChecksum(archiveScanner->GetArchiveCompleteChecksum(modArchive));
const std::string mapArchive = archiveScanner->ArchiveFromName(setup->mapName);
startupData->SetMapChecksum(archiveScanner->GetArchiveCompleteChecksum(mapArchive));

good_fpu_control_registers("before CGameServer creation");
startupData->SetSetup(setup->gameSetupText);
gameServer = new CGameServer(settings->hostport, (setup->playerStartingData.size() == 1), startupData, setup);
gameServer = new CGameServer(settings->hostport, startupData, setup);
delete startupData;
gameServer->AddLocalClient(settings->myPlayerName, SpringVersion::GetFull());
good_fpu_control_registers("after CGameServer creation");
Expand Down Expand Up @@ -313,6 +313,7 @@ void CPreGame::ReadDataFromDemo(const std::string& demoName)
tgame->AddPair("MapName", demoScript->mapName);
tgame->AddPair("Gametype", demoScript->modName);
tgame->AddPair("Demofile", demoName);
tgame->AddPair("OnlyLocal", 1);

for (std::map<std::string, TdfParser::TdfSection*>::iterator it = tgame->sections.begin(); it != tgame->sections.end(); ++it)
{
Expand Down Expand Up @@ -361,9 +362,11 @@ void CPreGame::ReadDataFromDemo(const std::string& demoName)
}
logOutput.Print("Starting GameServer");
good_fpu_control_registers("before CGameServer creation");
gameServer = new CGameServer(settings->hostport, true, data, tempSetup);

gameServer = new CGameServer(settings->hostport, data, tempSetup);
gameServer->AddLocalClient(settings->myPlayerName, SpringVersion::GetFull());
delete data;

good_fpu_control_registers("after CGameServer creation");
logOutput.Print("GameServer started");
break;
Expand Down
1 change: 1 addition & 0 deletions rts/Menu/SelectMenu.cpp
Expand Up @@ -138,6 +138,7 @@ std::string CreateDefaultSetup(const std::string& map, const std::string& mod, c
modopts->AddPair("MaxSpeed", 20);

game->AddPair("IsHost", 1);
game->AddPair("OnlyLocal", 1);
game->add_name_value("MyPlayerName", playername);

game->AddPair("NoHelperAIs", configHandler->Get("NoHelperAIs", 0));
Expand Down
53 changes: 33 additions & 20 deletions rts/System/Net/UDPListener.cpp
Expand Up @@ -29,36 +29,49 @@ using namespace boost::asio;

UDPListener::UDPListener(int port)
{
SocketPtr socket;

if (TryBindSocket(port, &socket)) {
boost::asio::socket_base::non_blocking_io socketCommand(true);
socket->io_control(socketCommand);

mySocket = socket;
acceptNewConnections = true;
}

if (!acceptNewConnections) {
handleerror(NULL, "[UDPListener] error: unable to bind UDP port.", "Network error", MBF_OK | MBF_EXCL);
} else {
LogObject() << "[UDPListener] succesfully bound socket on port " << port;
}
}

bool UDPListener::TryBindSocket(int port, SocketPtr* socket) const {
bool r = false;

try {
SocketPtr temp(new ip::udp::socket(netservice));
socket->reset(new ip::udp::socket(netservice));

boost::system::error_code err;
temp->open(ip::udp::v6(), err); // test v6
if (!err)
{
temp->bind(ip::udp::endpoint(ip::address_v6::any(), port));
}
else
{
(*socket)->open(ip::udp::v6(), err); // test v6

if (!err) {
(*socket)->bind(ip::udp::endpoint(ip::address_v6::any(), port));
} else {
// fallback to v4
temp->open(ip::udp::v4());
temp->bind(ip::udp::endpoint(ip::address_v4::any(), port));
(*socket)->open(ip::udp::v4());
(*socket)->bind(ip::udp::endpoint(ip::address_v4::any(), port));
}
boost::asio::socket_base::non_blocking_io command(true);
temp->io_control(command);

mySocket = temp;
acceptNewConnections = true;
r = true;
} catch (boost::system::system_error&) {
socket->reset();
}
catch(boost::system::system_error &) {
handleerror(NULL, "Error: Failed to initialize UDP.\nSpring may already be running.", "Network error", MBF_OK|MBF_EXCL);
}
}

UDPListener::~UDPListener()
{
return r;
}


void UDPListener::Update()
{
netservice.poll();
Expand Down
9 changes: 6 additions & 3 deletions rts/System/Net/UDPListener.h
Expand Up @@ -13,6 +13,7 @@
namespace netcode
{
class UDPConnection;
typedef boost::shared_ptr<boost::asio::ip::udp::socket> SocketPtr;

/**
* @brief Class for handling Connections on an UDPSocket
Expand All @@ -30,7 +31,9 @@ class UDPListener : boost::noncopyable
/**
@brief close the socket and DELETE all connections
*/
~UDPListener();
~UDPListener() {}

bool TryBindSocket(int port, SocketPtr* socket) const;

/**
@brief Run this from time to time
Expand Down Expand Up @@ -63,9 +66,9 @@ class UDPListener : boost::noncopyable
bool acceptNewConnections;

/// Our socket
typedef boost::shared_ptr<boost::asio::ip::udp::socket> SocketPtr;
/// typedef boost::shared_ptr<boost::asio::ip::udp::socket> SocketPtr;
SocketPtr mySocket;

/// all connections
std::list< boost::weak_ptr< UDPConnection> > conn;

Expand Down
2 changes: 1 addition & 1 deletion rts/builds/DS/main.cpp
Expand Up @@ -94,7 +94,7 @@ int main(int argc, char *argv[])
}

data.SetSetup(gameSetup->gameSetupText);
server = new CGameServer(settings.hostport, false, &data, gameSetup);
server = new CGameServer(settings.hostport, &data, gameSetup);

while (!server->HasFinished()) // check if still running
#ifdef _WIN32
Expand Down

0 comments on commit 7071a29

Please sign in to comment.