//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D 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 2 of the License, or // (at your option) any later version. // // Scorched3D 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 Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include ConnectDialog *ConnectDialog::instance_ = 0; ConnectDialog *ConnectDialog::instance() { if (!instance_) { instance_ = new ConnectDialog; } return instance_; } ConnectDialog::ConnectDialog() : GLWWindow("Connect", -100.0f, 10.0f, 20.0f, 20.0f, eNoDraw | eNoTitle, "Connection dialog"), connectionState_(eWaiting), tryCount_(0), lastTime_(0), idStore_(0) { } ConnectDialog::~ConnectDialog() { } UniqueIdStore &ConnectDialog::getIdStore() { if (!idStore_) { idStore_ = new UniqueIdStore(); // Get the unique id if (!idStore_->loadStore()) { LoggerInfo info (LoggerInfo::TypeNormal, "Failed to load id store", ""); LogDialog::instance()->logMessage(info); } } return *idStore_; } void ConnectDialog::simulate(float frameTime) { time_t currentTime = time(0); if (connectionState_ == eWaiting) { if (currentTime - lastTime_ > 3) { if (tryCount_<3) { lastTime_ = currentTime; tryConnection(); } } } else if (connectionState_ == eFinishedTryingConnection) { finishedTryingConnection(); } } void ConnectDialog::tryConnection() { const char *serverName = (OptionsParam::instance()->getConnect()[0]? OptionsParam::instance()->getConnect(): "Localhost"); std::string hostPart = serverName; char *colon = strchr((char *)serverName, ':'); int port = ScorchedPort; if (colon) { char *stop; *colon = '\0'; colon++; port = strtol(colon, &stop, 10); hostPart = serverName; colon--; *colon = ':'; } LogDialog::instance()->setServerName( formatString("Connecting to : %s", serverName)); { LoggerInfo info (LoggerInfo::TypeNormal, "Attempting connection", ""); LogDialog::instance()->logMessage(info); } { LoggerInfo info (LoggerInfo::TypeNormal, formatString(" Trying \"%s\"....", serverName[0]?serverName:"Loopback"), ""); LogDialog::instance()->logMessage(info); } connectionState_ = eTryingConnection; if (OptionsParam::instance()->getConnectedToServer()) { // This point should only ever be called by one thread // so cheat static ThreadParams params; params.host = hostPart; params.port = port; params.dialog = this; SDL_CreateThread(ConnectDialog::tryRemoteConnection, ¶ms); } else { tryLocalConnection(); } } int ConnectDialog::tryRemoteConnection(void *inParams) { ThreadParams *params = (ThreadParams *) inParams; char *host = (char *) params->host.c_str(); int port = params->port; ConnectDialog *dialog = params->dialog; if (ScorchedClient::instance()->getNetInterface(). connect(host, port)) { if (OptionsParam::instance()->getConnectedToServer()) { IPaddress address; if (SDLNet_ResolveHost(&address, host, 0) == 0) { unsigned int ipAddress = SDLNet_Read32(&address.host); dialog->uniqueId_ = dialog->getIdStore().getUniqueId(ipAddress); } } } dialog->connectionState_ = eFinishedTryingConnection; return 0; } void ConnectDialog::tryLocalConnection() { connectionState_ = eFinishedTryingConnection; } void ConnectDialog::finishedTryingConnection() { // Check to see if the connection attempt was successful if (!ScorchedClient::instance()->getNetInterface().started()) { LoggerInfo info (LoggerInfo::TypeNormal, " Connection Failed.", ""); LogDialog::instance()->logMessage(info); if (++tryCount_>2) { LoggerInfo info (LoggerInfo::TypeNormal, "Could not connect to server.", ""); LogDialog::instance()->logMessage(info); connectionState_ = eFinished; } else { connectionState_ = eWaiting; } return; } // Check the number of players that are connecting unsigned int noPlayers = 1; if (!OptionsParam::instance()->getConnectedToServer()) { noPlayers = ScorchedServer::instance()->getOptionsGame().getNoMaxPlayers() - ScorchedServer::instance()->getTankContainer().getNoOfTanks(); } // If we connected then send our details to the server ComsConnectMessage connectMessage; connectMessage.setVersion(ScorchedVersion); connectMessage.setProtocolVersion(ScorchedProtocolVersion); connectMessage.setUserName(OptionsParam::instance()->getUserName()); connectMessage.setPassword(OptionsParam::instance()->getPassword()); connectMessage.setUniqueId(uniqueId_.c_str()); connectMessage.setHostDesc(OptionsDisplay::instance()->getHostDescription()); connectMessage.setNoPlayers(noPlayers); if (!ComsMessageSender::sendToServer(connectMessage)) { LoggerInfo info (LoggerInfo::TypeNormal, " Connection Send Failed!", ""); LogDialog::instance()->logMessage(info); } connectionState_ = eFinished; }