00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <dialogs/NetworkSelectDialog.h>
00022 #include <dialogs/MsgBoxDialog.h>
00023 #include <GLW/GLWLabel.h>
00024 #include <GLW/GLWWindowManager.h>
00025 #include <GLW/GLWFont.h>
00026 #include <GLW/GLWTranslate.h>
00027 #include <graph/TextureStore.h>
00028 #include <serverbrowser/ServerBrowser.h>
00029 #include <client/ScorchedClient.h>
00030 #include <client/ClientParams.h>
00031 #include <client/ClientMain.h>
00032 #include <common/Defines.h>
00033 #include <common/OptionsScorched.h>
00034
00035 struct ColumnInfo
00036 {
00037 GLWIconTable::Column col;
00038 const char *dataName;
00039 };
00040 static ColumnInfo *getGamesCols()
00041 {
00042 static ColumnInfo gamescols[] =
00043 {
00044 GLWIconTable::Column(LANG_STRING(""), 60), "",
00045 GLWIconTable::Column(LANG_RESOURCE("SERVER_NAME", "Server Name"), 255), "servername",
00046 GLWIconTable::Column(LANG_RESOURCE("PLYRS", "Plyrs"), 60), "noplayers",
00047 GLWIconTable::Column(LANG_RESOURCE("ROUND", "Round"), 55), "round",
00048 GLWIconTable::Column(LANG_RESOURCE("MOD", "Mod"), 95), "mod",
00049 GLWIconTable::Column(LANG_RESOURCE("GAME_TYPE", "Game Type"), 200), "gametype",
00050 GLWIconTable::Column(LANG_STRING(""), -1), ""
00051 };
00052 return gamescols;
00053 }
00054
00055 static ColumnInfo *getPlayerCols()
00056 {
00057 static ColumnInfo playerscols[] =
00058 {
00059 GLWIconTable::Column(LANG_RESOURCE("PLAYER", "Player"), 270), "pn",
00060 GLWIconTable::Column(LANG_RESOURCE("SCORE", "Score"), 260), "ps",
00061 GLWIconTable::Column(LANG_RESOURCE("TIME", "Time"), 140), "pt",
00062 GLWIconTable::Column(LANG_RESOURCE("REAL", "Real"), 60), "pa",
00063 GLWIconTable::Column(LANG_STRING(""), -1), ""
00064 };
00065 return playerscols;
00066 }
00067
00068 NetworkSelectDialog *NetworkSelectDialog::instance_ = 0;
00069
00070 NetworkSelectDialog *NetworkSelectDialog::instance()
00071 {
00072 if (!instance_)
00073 {
00074 instance_ = new NetworkSelectDialog;
00075 }
00076 return instance_;
00077 }
00078
00079 NetworkSelectDialog::NetworkSelectDialog() :
00080 GLWWindow("", 780.0f, 560.0f, 0, ""),
00081 totalTime_(0.0f), invalidateId_(0),
00082 okTex_(0), questionTex_(0),
00083 warningTex_(0), noentryTex_(0),
00084 tankTex_(0)
00085 {
00086 std::list<GLWIconTable::Column> gamescolumns, playerscolumns;
00087 for (int i=0;; i++)
00088 {
00089 if (getGamesCols()[i].col.width == -1) break;
00090 gamescolumns.push_back(getGamesCols()[i].col);
00091 }
00092 for (int i=0;; i++)
00093 {
00094 if (getPlayerCols()[i].col.width == -1) break;
00095 playerscolumns.push_back(getPlayerCols()[i].col);
00096 }
00097
00098 gamesIconTable_ = new GLWIconTable(10.0f, 165.0f, 760.0f, 350.0f, &gamescolumns, 20.0f);
00099 addWidget(gamesIconTable_);
00100 gamesIconTable_->setHandler(this);
00101
00102 playersIconTable_ = new GLWIconTable(10.0f, 45.0f, 760.0f, 110.0f, &playerscolumns, 20.0f);
00103 addWidget(playersIconTable_);
00104 playersIconTable_->setHandler(this);
00105
00106 ok_ = (GLWTextButton *) addWidget(
00107 new GLWTextButton(LANG_RESOURCE("JOIN_GAME", "Join Game"), 640, 10, 130, this,
00108 GLWButton::ButtonFlagOk | GLWButton::ButtonFlagCenterX));
00109 cancelId_ = addWidget(
00110 new GLWTextButton(LANG_RESOURCE("CANCEL", "Cancel"), 530, 10, 105, this,
00111 GLWButton::ButtonFlagCancel | GLWButton::ButtonFlagCenterX))->getId();
00112 refresh_ = (GLWTextButton *) addWidget(
00113 new GLWTextButton(LANG_RESOURCE("REFRESH_LIST", "Refresh List"), 175, 10, 150, this,
00114 GLWButton::ButtonFlagCenterX));
00115 favourites_ = (GLWTextButton *) addWidget(
00116 new GLWTextButton(LANG_RESOURCE("ADD_FAVOURITE", "Add Favourite"), 10, 10, 155, this,
00117 GLWButton::ButtonFlagCenterX));
00118
00119 ipaddress_ = (GLWTextBox *) addWidget(
00120 new GLWTextBox(210.0f, 525.0f, 300.0));
00121 addWidget(new GLWLabel(75.0f, 525.0f, LANG_RESOURCE("CONNECT_TO_LABEL", "Connect To :")));
00122 ipaddress_->setHandler(this);
00123
00124 refreshType_ = (GLWDropDownText *) addWidget(
00125 new GLWDropDownText(530.0f, 525.0f, 150.0f));
00126 refreshType_->addText(LANG_RESOURCE("INTERNET", "Internet"), "Internet");
00127 refreshType_->addText(LANG_RESOURCE("LAN", "LAN"), "LAN");
00128 refreshType_->addText(LANG_RESOURCE("FAVOURITES", "Favourites"), "Favourites");
00129 refreshType_->setCurrentText(LANG_RESOURCE("INTERNET", "Internet"));
00130 refreshType_->setHandler(this);
00131
00132 ipaddress_->setCurrent();
00133 }
00134
00135 NetworkSelectDialog::~NetworkSelectDialog()
00136 {
00137
00138 }
00139
00140 void NetworkSelectDialog::simulate(float frameTime)
00141 {
00142 GLWWindow::simulate(frameTime);
00143
00144 totalTime_ += frameTime;
00145 if (totalTime_ > 1.0f)
00146 {
00147 updateTable();
00148 }
00149 }
00150
00151 void NetworkSelectDialog::drawIcon(GLTexture *tex, float &x, float y, LangString &message)
00152 {
00153 GLState state(GLState::TEXTURE_ON | GLState::BLEND_ON);
00154 glColor3f(1.0f, 1.0f, 1.0f);
00155 tex->draw();
00156
00157 float w = 18.0f;
00158 float h = 18.0f;
00159 glBegin(GL_QUADS);
00160 glTexCoord2f(0.0f, 0.0f);
00161 glVertex2f(x, y);
00162 glTexCoord2f(1.0f, 0.0f);
00163 glVertex2f(x + w, y);
00164 glTexCoord2f(1.0f, 1.0f);
00165 glVertex2f(x + w, y + h);
00166 glTexCoord2f(0.0f, 1.0f);
00167 glVertex2f(x, y + h);
00168 glEnd();
00169
00170 if (GLWToolTip::instance()->addToolTip(&colToolTip_,
00171 GLWTranslate::getPosX() + x,
00172 GLWTranslate::getPosY() + y,
00173 w, h))
00174 {
00175 colToolTip_.setText(ToolTip::ToolTipInfo,
00176 LANG_RESOURCE("STATUS_ICON", "Status Icon"), message);
00177 }
00178
00179 x += w;
00180 }
00181
00182 GLTexture *NetworkSelectDialog::getTexture(int row, LangString *&message)
00183 {
00184 std::string pversion =
00185 ServerBrowser::instance()->getServerList().
00186 getEntryValue(row, "protocolversion");
00187 std::string version =
00188 ServerBrowser::instance()->getServerList().
00189 getEntryValue(row, "version");
00190 if (!serverCompatable(pversion, version))
00191 {
00192 LANG_RESOURCE_CONST_VAR(INCOMPATIBLE,
00193 "INCOMPATIBLE_VERSION", "Incompatible version.");
00194 message = &INCOMPATIBLE;
00195 return noentryTex_;
00196 }
00197
00198 std::string clients =
00199 ServerBrowser::instance()->getServerList().
00200 getEntryValue(row, "noplayers");
00201 std::string maxclients =
00202 ServerBrowser::instance()->getServerList().
00203 getEntryValue(row, "maxplayers");
00204 if (clients.size() > 0 &&
00205 0 == strcmp(clients.c_str(), maxclients.c_str()))
00206 {
00207 LANG_RESOURCE_CONST_VAR(SERVER_FULL,
00208 "SERVER_FULL", "Server is full.");
00209 message = &SERVER_FULL;
00210 return exclaimTex_;
00211 }
00212
00213 std::string state =
00214 ServerBrowser::instance()->getServerList().
00215 getEntryValue(row, "state");
00216 if (0 == strcmp(state.c_str(), "Waiting"))
00217 {
00218 LANG_RESOURCE_CONST_VAR(NOT_STARTED,
00219 "GAME_NOT_STARTED", "Game has not started.");
00220 message = &NOT_STARTED;
00221 return warningTex_;
00222 }
00223 if (0 == strcmp(state.c_str(), "Started"))
00224 {
00225 LANG_RESOURCE_CONST_VAR(GAME_PROGESS,
00226 "GAME_IN_PROGRESS", "Game in progress and spaces on server.");
00227 message = &GAME_PROGESS;
00228 return okTex_;
00229 }
00230
00231 LANG_RESOURCE_CONST_VAR(CANNOT_CONTACT_SERVER,
00232 "CANNOT_CONTACT_SERVER", "Cannot contact server.");
00233 message = &CANNOT_CONTACT_SERVER;
00234 return questionTex_;
00235 }
00236
00237 void NetworkSelectDialog::drawColumn(unsigned int id, int row, int col,
00238 float x, float y, float w)
00239 {
00240 if (id == gamesIconTable_->getId()) drawColumnGames(id, row, col, x, y, w);
00241 else if (id == playersIconTable_->getId()) drawColumnPlayers(id, row, col, x, y, w);
00242 }
00243
00244 void NetworkSelectDialog::drawColumnGames(unsigned int id, int row, int col,
00245 float x, float y, float w)
00246 {
00247 if (row < 0 || row >= ServerBrowser::instance()->getServerList().getNoEntries())
00248 {
00249 return;
00250 }
00251
00252 std::string value, tipValue;
00253 if (col == 0)
00254 {
00255 if (!okTex_)
00256 {
00257 okTex_ = TextureStore::instance()->loadTexture(
00258 S3D::getDataFile("data/windows/ok.bmp"),
00259 S3D::getDataFile("data/windows/mask.bmp"));
00260 questionTex_ = TextureStore::instance()->loadTexture(
00261 S3D::getDataFile("data/windows/question.bmp"),
00262 S3D::getDataFile("data/windows/mask.bmp"));
00263 warningTex_ = TextureStore::instance()->loadTexture(
00264 S3D::getDataFile("data/windows/warn.bmp"),
00265 S3D::getDataFile("data/windows/mask.bmp"));
00266 noentryTex_ = TextureStore::instance()->loadTexture(
00267 S3D::getDataFile("data/windows/noentry.bmp"),
00268 S3D::getDataFile("data/windows/mask.bmp"));
00269 exclaimTex_ = TextureStore::instance()->loadTexture(
00270 S3D::getDataFile("data/windows/exclaim.bmp"),
00271 S3D::getDataFile("data/windows/mask.bmp"));
00272 keyTex_ = TextureStore::instance()->loadTexture(
00273 S3D::getDataFile("data/windows/key.bmp"),
00274 S3D::getDataFile("data/windows/keya.bmp"),
00275 true);
00276 cogTex_ = TextureStore::instance()->loadTexture(
00277 S3D::getDataFile("data/windows/cog.bmp"),
00278 S3D::getDataFile("data/windows/coga.bmp"),
00279 true);
00280 tankTex_ = TextureStore::instance()->loadTexture(
00281 S3D::getDataFile("data/windows/tank2s.bmp"));
00282 }
00283
00284 LANG_RESOURCE_CONST_VAR(NONE, "NONE", "None");
00285
00286 {
00287 LangString *message = &NONE;
00288 GLTexture *tex = getTexture(row, message);
00289 drawIcon(tex, x, y, *message);
00290 }
00291
00292 std::string key =
00293 ServerBrowser::instance()->getServerList().
00294 getEntryValue(row, "password");
00295 if (0 == strcmp(key.c_str(), "On"))
00296 {
00297 LANG_RESOURCE_CONST_VAR(
00298 PASSWORD_PROTECTED, "PASSWORD_PROTECTED", "Password protected.");
00299 drawIcon(keyTex_, x, y, PASSWORD_PROTECTED);
00300 }
00301
00302 std::string officialStr =
00303 ServerBrowser::instance()->getServerList().
00304 getEntryValue(row, "type");
00305 if (officialStr == "official")
00306 {
00307 LANG_RESOURCE_CONST_VAR(
00308 OFFICAL_SERVER, "OFFICAL_SERVER", "An offical server.");
00309 drawIcon(tankTex_, x, y, OFFICAL_SERVER);
00310 }
00311 else if (officialStr == "mod")
00312 {
00313 LANG_RESOURCE_CONST_VAR(
00314 MOD_SERVER, "MOD_SERVER", "Home of mod server.");
00315 drawIcon(cogTex_, x, y, MOD_SERVER);
00316 }
00317 }
00318 else if (col == 2)
00319 {
00320 std::string clients =
00321 ServerBrowser::instance()->getServerList().
00322 getEntryValue(row, "noplayers");
00323 std::string maxclients =
00324 ServerBrowser::instance()->getServerList().
00325 getEntryValue(row, "maxplayers");
00326 std::string compplayers =
00327 ServerBrowser::instance()->getServerList().
00328 getEntryValue(row, "compplayers");
00329
00330 std::string name;
00331 if (compplayers.c_str()[0])
00332 {
00333 name = S3D::formatStringBuffer("%s/%s (%i)", clients.c_str(), maxclients.c_str(),
00334 (atoi(clients.c_str()) - atoi(compplayers.c_str())));
00335 }
00336 else
00337 {
00338 name = S3D::formatStringBuffer("%s/%s (?)", clients.c_str(), maxclients.c_str());
00339 }
00340
00341 std::string message = name;
00342 int noplayers = atoi(clients.c_str());
00343 for (int i=0; i<noplayers; i++)
00344 {
00345 std::string pn =
00346 ServerBrowser::instance()->getServerList().getEntryValue(
00347 row, S3D::formatStringBuffer("pn%i", i));
00348 std::string pa =
00349 ServerBrowser::instance()->getServerList().getEntryValue(
00350 row, S3D::formatStringBuffer("pa%i", i));
00351
00352 message.append(S3D::formatStringBuffer("\n%i: %s: %s",
00353 i, pa.c_str(), pn.c_str()));
00354 }
00355
00356 value = S3D::formatStringBuffer("%s", name.c_str());
00357 tipValue = S3D::formatStringBuffer("%s", message.c_str());
00358 }
00359 else
00360 {
00361 tipValue = value = ServerBrowser::instance()->getServerList().getEntryValue(row, getGamesCols()[col].dataName);
00362 if (value[0] == '\0' && col == 1)
00363 {
00364 tipValue = value = ServerBrowser::instance()->getServerList().getEntryValue(row, "address");
00365 }
00366 }
00367
00368 if (!value.empty())
00369 {
00370 Vector color(0.3f, 0.3f, 0.3f);
00371 GLWFont::instance()->getGameFont()->drawWidth(w,
00372 color,
00373 10.0f, x + 3.0f, y + 5.0f, 0.0f, value);
00374
00375 if (!tipValue.empty())
00376 {
00377 if (GLWToolTip::instance()->addToolTip(&colToolTip_,
00378 GLWTranslate::getPosX() + x,
00379 GLWTranslate::getPosY() + y,
00380 w, 20.0f))
00381 {
00382 colToolTip_.setText(ToolTip::ToolTipInfo,
00383 getGamesCols()[col].col.name,
00384 LANG_STRING(tipValue));
00385 }
00386 }
00387 }
00388 }
00389
00390 void NetworkSelectDialog::drawColumnPlayers(unsigned int id, int row, int col,
00391 float x, float y, float w)
00392 {
00393 int gamesrow = gamesIconTable_->getSelected();
00394 if (gamesrow < 0 || gamesrow >= ServerBrowser::instance()->getServerList().getNoEntries())
00395 {
00396 return;
00397 }
00398
00399 std::string valuestr =
00400 ServerBrowser::instance()->getServerList().getEntryValue(
00401 gamesrow, S3D::formatStringBuffer("%s%i", getPlayerCols()[col].dataName, row));
00402 const char *value = valuestr.c_str();
00403
00404 Vector color(0.3f, 0.3f, 0.3f);
00405 GLWFont::instance()->getGameFont()->drawWidth(w,
00406 color,
00407 10.0f, x + 3.0f, y + 5.0f, 0.0f, value);
00408 }
00409
00410 bool NetworkSelectDialog::serverCompatable(std::string pversion, std::string version)
00411 {
00412 if (pversion.size() > 0 &&
00413 0 != strcmp(pversion.c_str(), S3D::ScorchedProtocolVersion.c_str()))
00414 {
00415 return false;
00416 }
00417
00418 return true;
00419 }
00420
00421 void NetworkSelectDialog::rowSelected(unsigned int id, int row)
00422 {
00423 if (id == gamesIconTable_->getId()) rowSelectedGames(id, row);
00424 }
00425
00426 void NetworkSelectDialog::rowSelectedGames(unsigned int id, int row)
00427 {
00428 if (row < 0 || row >= ServerBrowser::instance()->getServerList().getNoEntries())
00429 {
00430 return;
00431 }
00432
00433
00434 std::string ipaddress = ServerBrowser::instance()->
00435 getServerList().getEntryValue(row, "address");
00436 if (ipaddress.empty()) return;
00437
00438
00439 std::string protocolVersion =
00440 ServerBrowser::instance()->getServerList().getEntryValue(row, "protocolversion");
00441 std::string version =
00442 ServerBrowser::instance()->getServerList().getEntryValue(row, "version");
00443 if (!serverCompatable(protocolVersion, version))
00444 {
00445 LangString msg = LANG_RESOURCE_4("INCOMPATIBLE_VERSION_WARNING",
00446 "Warning: This server is running a incompatable version of Scorched3D.\n"
00447 "You cannot connect to this server.\n\n"
00448 "This server is running Scorched build {0} ({1}).\n"
00449 "You are running Scorched build {2} ({3}).\n\n"
00450 "The latest version of Scorched3D can be downloaded from \n"
00451 "http://www.scorched3d.co.uk\n",
00452 version, protocolVersion,
00453 S3D::ScorchedVersion, S3D::ScorchedProtocolVersion);
00454 MsgBoxDialog::instance()->show(msg);
00455 }
00456
00457
00458 ipaddress_->setText(LANG_STRING(ipaddress));
00459
00460
00461 std::string players =
00462 ServerBrowser::instance()->getServerList().getEntryValue(row, "noplayers");
00463 int noplayers = atoi(players.c_str());
00464 playersIconTable_->setItemCount(noplayers);
00465 }
00466
00467 void NetworkSelectDialog::rowChosen(unsigned int id, int row)
00468 {
00469 if (id == gamesIconTable_->getId()) rowChosenGames(id, row);
00470 }
00471
00472 void NetworkSelectDialog::rowChosenGames(unsigned int id, int row)
00473 {
00474 if (ok_->getEnabled()) buttonDown(ok_->getId());
00475 }
00476
00477 void NetworkSelectDialog::columnSelected(unsigned int id, int col)
00478 {
00479 if (id == gamesIconTable_->getId()) columnSelectedGames(id, col);
00480 }
00481
00482 void NetworkSelectDialog::columnSelectedGames(unsigned int id, int col)
00483 {
00484 ServerBrowser::instance()->getServerList().sortEntries(getGamesCols()[col].dataName);
00485 }
00486
00487 void NetworkSelectDialog::display()
00488 {
00489 ipaddress_->setText(LangString());
00490 refreshType_->setCurrentText(LANG_RESOURCE("INTERNET", "Internet"));
00491 }
00492
00493 void NetworkSelectDialog::hide()
00494 {
00495 stopRefresh();
00496 }
00497
00498 void NetworkSelectDialog::updateTable()
00499 {
00500
00501
00502 if (!ServerBrowser::instance()->getRefreshing())
00503 {
00504 refresh_->setText(LANG_RESOURCE("REFRESH_LIST", "Refresh List"));
00505 }
00506 else
00507 {
00508 refresh_->setText(LANG_RESOURCE("STOP_REFRESH", "Stop Refresh"));
00509 }
00510
00511
00512 if (invalidateId_ != ServerBrowser::instance()->
00513 getServerList().getRefreshId())
00514 {
00515 invalidateId_ = ServerBrowser::instance()->
00516 getServerList().getRefreshId();
00517 gamesIconTable_->setItemCount(
00518 ServerBrowser::instance()->getServerList().getNoEntries());
00519 }
00520 }
00521
00522 void NetworkSelectDialog::select(unsigned int id, const int pos, GLWSelectorEntry value)
00523 {
00524 if (refreshType_->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites")))
00525 {
00526 favourites_->setText(LANG_RESOURCE("DELETE_FAVOURITE", "Del Favourite"));
00527 }
00528 else
00529 {
00530 favourites_->setText(LANG_RESOURCE("ADD_FAVOURITE", "Add Favourite"));
00531 }
00532
00533 startRefresh();
00534 }
00535
00536 void NetworkSelectDialog::startRefresh()
00537 {
00538 stopRefresh();
00539
00540 gamesIconTable_->setItemCount(0);
00541 playersIconTable_->setItemCount(0);
00542
00543 ServerBrowser::RefreshType t = ServerBrowser::RefreshNone;
00544 if (refreshType_->isSelected(LANG_RESOURCE("LAN", "LAN"))) t = ServerBrowser::RefreshLan;
00545 else if (refreshType_->isSelected(LANG_RESOURCE("INTERNET", "Internet"))) t = ServerBrowser::RefreshNet;
00546 else if (refreshType_->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites"))) t = ServerBrowser::RefreshFavourites;
00547
00548 ServerBrowser::instance()->refreshList(t);
00549 updateTable();
00550 }
00551
00552 void NetworkSelectDialog::stopRefresh()
00553 {
00554 ServerBrowser::instance()->cancel();
00555 updateTable();
00556 }
00557
00558 void NetworkSelectDialog::textChanged(unsigned int id, const LangString &text)
00559 {
00560 ok_->setEnabled(text[0]!='\0');
00561 favourites_->setEnabled(text[0]!='\0');
00562 }
00563
00564 void NetworkSelectDialog::buttonDown(unsigned int id)
00565 {
00566 if (id == refresh_->getId())
00567 {
00568 if (ServerBrowser::instance()->getRefreshing())
00569 {
00570 stopRefresh();
00571 }
00572 else
00573 {
00574 startRefresh();
00575 }
00576 }
00577 else if (id == ok_->getId())
00578 {
00579 GLWWindowManager::instance()->hideWindow(id_);
00580
00581 if (ipaddress_->getText()[0])
00582 {
00583 ClientParams::instance()->reset();
00584 ClientParams::instance()->setConnect(ipaddress_->getText().c_str());
00585 ClientMain::startClient();
00586 }
00587 }
00588 else if (id == favourites_->getId())
00589 {
00590 if (!ipaddress_->getText().empty())
00591 {
00592 std::set<std::string> favs =
00593 ServerBrowser::instance()->getCollect().getFavourites();
00594
00595 if (refreshType_->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites")))
00596 {
00597 favs.erase(ipaddress_->getText().c_str());
00598 }
00599 else
00600 {
00601 favs.insert(ipaddress_->getText().c_str());
00602 }
00603 ServerBrowser::instance()->getCollect().setFavourites(favs);
00604
00605 if (refreshType_->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites")))
00606 {
00607 startRefresh();
00608 }
00609 }
00610 }
00611 else if (id == cancelId_)
00612 {
00613 GLWWindowManager::instance()->hideWindow(id_);
00614 }
00615 }