git-svn-id: https://scorched3d.svn.sourceforge.net/svnroot/scorched3d/trunk/scorched...
[scorched3d/parasti.git] / src / client / dialogs / NetworkSelectDialog.cpp
blob837e4f6e041192eae125e32ffb4c9c1c1aef0546
1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <dialogs/NetworkSelectDialog.h>
22 #include <dialogs/MsgBoxDialog.h>
23 #include <GLW/GLWLabel.h>
24 #include <GLW/GLWWindowManager.h>
25 #include <GLW/GLWFont.h>
26 #include <GLW/GLWTranslate.h>
27 #include <graph/TextureStore.h>
28 #include <serverbrowser/ServerBrowser.h>
29 #include <client/ScorchedClient.h>
30 #include <client/ClientParams.h>
31 #include <client/ClientMain.h>
32 #include <common/Defines.h>
33 #include <common/OptionsScorched.h>
35 struct ColumnInfo
37 GLWIconTable::Column col;
38 const char *dataName;
40 static ColumnInfo *getGamesCols()
42 static ColumnInfo gamescols[] =
44 GLWIconTable::Column(LANG_STRING(""), 60), "",
45 GLWIconTable::Column(LANG_RESOURCE("SERVER_NAME", "Server Name"), 255), "servername",
46 GLWIconTable::Column(LANG_RESOURCE("PLYRS", "Plyrs"), 60), "noplayers",
47 GLWIconTable::Column(LANG_RESOURCE("ROUND", "Round"), 55), "round",
48 GLWIconTable::Column(LANG_RESOURCE("MOD", "Mod"), 95), "mod",
49 GLWIconTable::Column(LANG_RESOURCE("GAME_TYPE", "Game Type"), 200), "gametype",
50 GLWIconTable::Column(LANG_STRING(""), -1), ""
52 return gamescols;
55 static ColumnInfo *getPlayerCols()
57 static ColumnInfo playerscols[] =
59 GLWIconTable::Column(LANG_RESOURCE("PLAYER", "Player"), 270), "pn",
60 GLWIconTable::Column(LANG_RESOURCE("SCORE", "Score"), 260), "ps",
61 GLWIconTable::Column(LANG_RESOURCE("TIME", "Time"), 140), "pt",
62 GLWIconTable::Column(LANG_RESOURCE("REAL", "Real"), 60), "pa",
63 GLWIconTable::Column(LANG_STRING(""), -1), ""
65 return playerscols;
68 NetworkSelectDialog *NetworkSelectDialog::instance_ = 0;
70 NetworkSelectDialog *NetworkSelectDialog::instance()
72 if (!instance_)
74 instance_ = new NetworkSelectDialog;
76 return instance_;
79 NetworkSelectDialog::NetworkSelectDialog() :
80 GLWWindow("", 780.0f, 560.0f, 0, ""),
81 totalTime_(0.0f), invalidateId_(0),
82 okTex_(0), questionTex_(0),
83 warningTex_(0), noentryTex_(0),
84 tankTex_(0)
86 std::list<GLWIconTable::Column> gamescolumns, playerscolumns;
87 for (int i=0;; i++)
89 if (getGamesCols()[i].col.width == -1) break;
90 gamescolumns.push_back(getGamesCols()[i].col);
92 for (int i=0;; i++)
94 if (getPlayerCols()[i].col.width == -1) break;
95 playerscolumns.push_back(getPlayerCols()[i].col);
98 gamesIconTable_ = new GLWIconTable(10.0f, 165.0f, 760.0f, 350.0f, &gamescolumns, 20.0f);
99 addWidget(gamesIconTable_);
100 gamesIconTable_->setHandler(this);
102 playersIconTable_ = new GLWIconTable(10.0f, 45.0f, 760.0f, 110.0f, &playerscolumns, 20.0f);
103 addWidget(playersIconTable_);
104 playersIconTable_->setHandler(this);
106 ok_ = (GLWTextButton *) addWidget(
107 new GLWTextButton(LANG_RESOURCE("JOIN_GAME", "Join Game"), 640, 10, 130, this,
108 GLWButton::ButtonFlagOk | GLWButton::ButtonFlagCenterX));
109 cancelId_ = addWidget(
110 new GLWTextButton(LANG_RESOURCE("CANCEL", "Cancel"), 530, 10, 105, this,
111 GLWButton::ButtonFlagCancel | GLWButton::ButtonFlagCenterX))->getId();
112 refresh_ = (GLWTextButton *) addWidget(
113 new GLWTextButton(LANG_RESOURCE("REFRESH_LIST", "Refresh List"), 175, 10, 150, this,
114 GLWButton::ButtonFlagCenterX));
115 favourites_ = (GLWTextButton *) addWidget(
116 new GLWTextButton(LANG_RESOURCE("ADD_FAVOURITE", "Add Favourite"), 10, 10, 155, this,
117 GLWButton::ButtonFlagCenterX));
119 ipaddress_ = (GLWTextBox *) addWidget(
120 new GLWTextBox(210.0f, 525.0f, 300.0));
121 addWidget(new GLWLabel(75.0f, 525.0f, LANG_RESOURCE("CONNECT_TO_LABEL", "Connect To :")));
122 ipaddress_->setHandler(this);
124 refreshType_ = (GLWDropDownText *) addWidget(
125 new GLWDropDownText(530.0f, 525.0f, 150.0f));
126 refreshType_->addText(LANG_RESOURCE("INTERNET", "Internet"), "Internet");
127 refreshType_->addText(LANG_RESOURCE("LAN", "LAN"), "LAN");
128 refreshType_->addText(LANG_RESOURCE("FAVOURITES", "Favourites"), "Favourites");
129 refreshType_->setCurrentText(LANG_RESOURCE("INTERNET", "Internet"));
130 refreshType_->setHandler(this);
132 ipaddress_->setCurrent();
135 NetworkSelectDialog::~NetworkSelectDialog()
140 void NetworkSelectDialog::simulate(float frameTime)
142 GLWWindow::simulate(frameTime);
144 totalTime_ += frameTime;
145 if (totalTime_ > 1.0f)
147 updateTable();
151 void NetworkSelectDialog::drawIcon(GLTexture *tex, float &x, float y, LangString &message)
153 GLState state(GLState::TEXTURE_ON | GLState::BLEND_ON);
154 glColor3f(1.0f, 1.0f, 1.0f);
155 tex->draw();
157 float w = 18.0f;
158 float h = 18.0f;
159 glBegin(GL_QUADS);
160 glTexCoord2f(0.0f, 0.0f);
161 glVertex2f(x, y);
162 glTexCoord2f(1.0f, 0.0f);
163 glVertex2f(x + w, y);
164 glTexCoord2f(1.0f, 1.0f);
165 glVertex2f(x + w, y + h);
166 glTexCoord2f(0.0f, 1.0f);
167 glVertex2f(x, y + h);
168 glEnd();
170 if (GLWToolTip::instance()->addToolTip(&colToolTip_,
171 GLWTranslate::getPosX() + x,
172 GLWTranslate::getPosY() + y,
173 w, h))
175 colToolTip_.setText(ToolTip::ToolTipInfo,
176 LANG_RESOURCE("STATUS_ICON", "Status Icon"), message);
179 x += w;
182 GLTexture *NetworkSelectDialog::getTexture(int row, LangString *&message)
184 std::string pversion =
185 ServerBrowser::instance()->getServerList().
186 getEntryValue(row, "protocolversion");
187 std::string version =
188 ServerBrowser::instance()->getServerList().
189 getEntryValue(row, "version");
190 if (!serverCompatable(pversion, version))
192 LANG_RESOURCE_CONST_VAR(INCOMPATIBLE,
193 "INCOMPATIBLE_VERSION", "Incompatible version.");
194 message = &INCOMPATIBLE;
195 return noentryTex_;
198 std::string clients =
199 ServerBrowser::instance()->getServerList().
200 getEntryValue(row, "noplayers");
201 std::string maxclients =
202 ServerBrowser::instance()->getServerList().
203 getEntryValue(row, "maxplayers");
204 if (clients.size() > 0 &&
205 0 == strcmp(clients.c_str(), maxclients.c_str()))
207 LANG_RESOURCE_CONST_VAR(SERVER_FULL,
208 "SERVER_FULL", "Server is full.");
209 message = &SERVER_FULL;
210 return exclaimTex_;
213 std::string state =
214 ServerBrowser::instance()->getServerList().
215 getEntryValue(row, "state");
216 if (0 == strcmp(state.c_str(), "Waiting"))
218 LANG_RESOURCE_CONST_VAR(NOT_STARTED,
219 "GAME_NOT_STARTED", "Game has not started.");
220 message = &NOT_STARTED;
221 return warningTex_;
223 if (0 == strcmp(state.c_str(), "Started"))
225 LANG_RESOURCE_CONST_VAR(GAME_PROGESS,
226 "GAME_IN_PROGRESS", "Game in progress and spaces on server.");
227 message = &GAME_PROGESS;
228 return okTex_;
231 LANG_RESOURCE_CONST_VAR(CANNOT_CONTACT_SERVER,
232 "CANNOT_CONTACT_SERVER", "Cannot contact server.");
233 message = &CANNOT_CONTACT_SERVER;
234 return questionTex_;
237 void NetworkSelectDialog::drawColumn(unsigned int id, int row, int col,
238 float x, float y, float w)
240 if (id == gamesIconTable_->getId()) drawColumnGames(id, row, col, x, y, w);
241 else if (id == playersIconTable_->getId()) drawColumnPlayers(id, row, col, x, y, w);
244 void NetworkSelectDialog::drawColumnGames(unsigned int id, int row, int col,
245 float x, float y, float w)
247 if (row < 0 || row >= ServerBrowser::instance()->getServerList().getNoEntries())
249 return;
252 std::string value, tipValue;
253 if (col == 0)
255 if (!okTex_)
257 okTex_ = TextureStore::instance()->loadTexture(
258 S3D::getDataFile("data/windows/ok.bmp"),
259 S3D::getDataFile("data/windows/mask.bmp"));
260 questionTex_ = TextureStore::instance()->loadTexture(
261 S3D::getDataFile("data/windows/question.bmp"),
262 S3D::getDataFile("data/windows/mask.bmp"));
263 warningTex_ = TextureStore::instance()->loadTexture(
264 S3D::getDataFile("data/windows/warn.bmp"),
265 S3D::getDataFile("data/windows/mask.bmp"));
266 noentryTex_ = TextureStore::instance()->loadTexture(
267 S3D::getDataFile("data/windows/noentry.bmp"),
268 S3D::getDataFile("data/windows/mask.bmp"));
269 exclaimTex_ = TextureStore::instance()->loadTexture(
270 S3D::getDataFile("data/windows/exclaim.bmp"),
271 S3D::getDataFile("data/windows/mask.bmp"));
272 keyTex_ = TextureStore::instance()->loadTexture(
273 S3D::getDataFile("data/windows/key.bmp"),
274 S3D::getDataFile("data/windows/keya.bmp"),
275 true);
276 cogTex_ = TextureStore::instance()->loadTexture(
277 S3D::getDataFile("data/windows/cog.bmp"),
278 S3D::getDataFile("data/windows/coga.bmp"),
279 true);
280 tankTex_ = TextureStore::instance()->loadTexture(
281 S3D::getDataFile("data/windows/tank2s.bmp"));
284 LANG_RESOURCE_CONST_VAR(NONE, "NONE", "None");
287 LangString *message = &NONE;
288 GLTexture *tex = getTexture(row, message);
289 drawIcon(tex, x, y, *message);
292 std::string key =
293 ServerBrowser::instance()->getServerList().
294 getEntryValue(row, "password");
295 if (0 == strcmp(key.c_str(), "On"))
297 LANG_RESOURCE_CONST_VAR(
298 PASSWORD_PROTECTED, "PASSWORD_PROTECTED", "Password protected.");
299 drawIcon(keyTex_, x, y, PASSWORD_PROTECTED);
302 std::string officialStr =
303 ServerBrowser::instance()->getServerList().
304 getEntryValue(row, "type");
305 if (officialStr == "official")
307 LANG_RESOURCE_CONST_VAR(
308 OFFICAL_SERVER, "OFFICAL_SERVER", "An offical server.");
309 drawIcon(tankTex_, x, y, OFFICAL_SERVER);
311 else if (officialStr == "mod")
313 LANG_RESOURCE_CONST_VAR(
314 MOD_SERVER, "MOD_SERVER", "Home of mod server.");
315 drawIcon(cogTex_, x, y, MOD_SERVER);
318 else if (col == 2)
320 std::string clients =
321 ServerBrowser::instance()->getServerList().
322 getEntryValue(row, "noplayers");
323 std::string maxclients =
324 ServerBrowser::instance()->getServerList().
325 getEntryValue(row, "maxplayers");
326 std::string compplayers =
327 ServerBrowser::instance()->getServerList().
328 getEntryValue(row, "compplayers");
330 std::string name;
331 if (compplayers.c_str()[0])
333 name = S3D::formatStringBuffer("%s/%s (%i)", clients.c_str(), maxclients.c_str(),
334 (atoi(clients.c_str()) - atoi(compplayers.c_str())));
336 else
338 name = S3D::formatStringBuffer("%s/%s (?)", clients.c_str(), maxclients.c_str());
341 std::string message = name;
342 int noplayers = atoi(clients.c_str());
343 for (int i=0; i<noplayers; i++)
345 std::string pn =
346 ServerBrowser::instance()->getServerList().getEntryValue(
347 row, S3D::formatStringBuffer("pn%i", i));
348 std::string pa =
349 ServerBrowser::instance()->getServerList().getEntryValue(
350 row, S3D::formatStringBuffer("pa%i", i));
352 message.append(S3D::formatStringBuffer("\n%i: %s: %s",
353 i, pa.c_str(), pn.c_str()));
356 value = S3D::formatStringBuffer("%s", name.c_str());
357 tipValue = S3D::formatStringBuffer("%s", message.c_str());
359 else
361 tipValue = value = ServerBrowser::instance()->getServerList().getEntryValue(row, getGamesCols()[col].dataName);
362 if (value[0] == '\0' && col == 1)
364 tipValue = value = ServerBrowser::instance()->getServerList().getEntryValue(row, "address");
368 if (!value.empty())
370 Vector color(0.3f, 0.3f, 0.3f);
371 GLWFont::instance()->getGameFont()->drawWidth(w,
372 color,
373 10.0f, x + 3.0f, y + 5.0f, 0.0f, value);
375 if (!tipValue.empty())
377 if (GLWToolTip::instance()->addToolTip(&colToolTip_,
378 GLWTranslate::getPosX() + x,
379 GLWTranslate::getPosY() + y,
380 w, 20.0f))
382 colToolTip_.setText(ToolTip::ToolTipInfo,
383 getGamesCols()[col].col.name,
384 LANG_STRING(tipValue));
390 void NetworkSelectDialog::drawColumnPlayers(unsigned int id, int row, int col,
391 float x, float y, float w)
393 int gamesrow = gamesIconTable_->getSelected();
394 if (gamesrow < 0 || gamesrow >= ServerBrowser::instance()->getServerList().getNoEntries())
396 return;
399 std::string valuestr =
400 ServerBrowser::instance()->getServerList().getEntryValue(
401 gamesrow, S3D::formatStringBuffer("%s%i", getPlayerCols()[col].dataName, row));
402 const char *value = valuestr.c_str();
404 Vector color(0.3f, 0.3f, 0.3f);
405 GLWFont::instance()->getGameFont()->drawWidth(w,
406 color,
407 10.0f, x + 3.0f, y + 5.0f, 0.0f, value);
410 bool NetworkSelectDialog::serverCompatable(std::string pversion, std::string version)
412 if (pversion.size() > 0 &&
413 0 != strcmp(pversion.c_str(), S3D::ScorchedProtocolVersion.c_str()))
415 return false;
418 return true;
421 void NetworkSelectDialog::rowSelected(unsigned int id, int row)
423 if (id == gamesIconTable_->getId()) rowSelectedGames(id, row);
426 void NetworkSelectDialog::rowSelectedGames(unsigned int id, int row)
428 if (row < 0 || row >= ServerBrowser::instance()->getServerList().getNoEntries())
430 return;
433 // Check if we have any information for this row
434 std::string ipaddress = ServerBrowser::instance()->
435 getServerList().getEntryValue(row, "address");
436 if (ipaddress.empty()) return;
438 // Check if this server is compatible
439 std::string protocolVersion =
440 ServerBrowser::instance()->getServerList().getEntryValue(row, "protocolversion");
441 std::string version =
442 ServerBrowser::instance()->getServerList().getEntryValue(row, "version");
443 if (!serverCompatable(protocolVersion, version))
445 MsgBoxDialog::instance()->show(
446 S3D::formatStringBuffer(
447 "Warning: This server is running a incompatable version of Scorched3D.\n"
448 "You cannot connect to this server.\n\n"
449 "This server is running Scorched build %s (%s).\n"
450 "You are running Scorched build %s (%s).\n\n"
451 "The latest version of Scorched3D can be downloaded from \n"
452 "http://www.scorched3d.co.uk\n",
453 version.c_str(), protocolVersion.c_str(),
454 S3D::ScorchedVersion.c_str(), S3D::ScorchedProtocolVersion.c_str()));
457 // Set ip address for this server
458 ipaddress_->setText(LANG_STRING(ipaddress));
460 // Set players for this server
461 std::string players =
462 ServerBrowser::instance()->getServerList().getEntryValue(row, "noplayers");
463 int noplayers = atoi(players.c_str());
464 playersIconTable_->setItemCount(noplayers);
467 void NetworkSelectDialog::rowChosen(unsigned int id, int row)
469 if (id == gamesIconTable_->getId()) rowChosenGames(id, row);
472 void NetworkSelectDialog::rowChosenGames(unsigned int id, int row)
474 if (ok_->getEnabled()) buttonDown(ok_->getId());
477 void NetworkSelectDialog::columnSelected(unsigned int id, int col)
479 if (id == gamesIconTable_->getId()) columnSelectedGames(id, col);
482 void NetworkSelectDialog::columnSelectedGames(unsigned int id, int col)
484 ServerBrowser::instance()->getServerList().sortEntries(getGamesCols()[col].dataName);
487 void NetworkSelectDialog::display()
489 ipaddress_->setText(LangString());
490 refreshType_->setCurrentText(LANG_RESOURCE("INTERNET", "Internet"));
493 void NetworkSelectDialog::hide()
495 stopRefresh();
498 void NetworkSelectDialog::updateTable()
500 // Check if we are refreshing
501 // Set the button accordingly
502 if (!ServerBrowser::instance()->getRefreshing())
504 refresh_->setText(LANG_RESOURCE("REFRESH_LIST", "Refresh List"));
506 else
508 refresh_->setText(LANG_RESOURCE("STOP_REFRESH", "Stop Refresh"));
511 // Check if we have more items to display
512 if (invalidateId_ != ServerBrowser::instance()->
513 getServerList().getRefreshId())
515 invalidateId_ = ServerBrowser::instance()->
516 getServerList().getRefreshId();
517 gamesIconTable_->setItemCount(
518 ServerBrowser::instance()->getServerList().getNoEntries());
522 void NetworkSelectDialog::select(unsigned int id, const int pos, GLWSelectorEntry value)
524 if (refreshType_->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites")))
526 favourites_->setText(LANG_RESOURCE("DELETE_FAVOURITE", "Del Favourite"));
528 else
530 favourites_->setText(LANG_RESOURCE("ADD_FAVOURITE", "Add Favourite"));
533 startRefresh();
536 void NetworkSelectDialog::startRefresh()
538 stopRefresh();
540 gamesIconTable_->setItemCount(0);
541 playersIconTable_->setItemCount(0);
543 ServerBrowser::RefreshType t = ServerBrowser::RefreshNone;
544 if (refreshType_->isSelected(LANG_RESOURCE("LAN", "LAN"))) t = ServerBrowser::RefreshLan;
545 else if (refreshType_->isSelected(LANG_RESOURCE("INTERNET", "Internet"))) t = ServerBrowser::RefreshNet;
546 else if (refreshType_->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites"))) t = ServerBrowser::RefreshFavourites;
548 ServerBrowser::instance()->refreshList(t);
549 updateTable();
552 void NetworkSelectDialog::stopRefresh()
554 ServerBrowser::instance()->cancel();
555 updateTable();
558 void NetworkSelectDialog::textChanged(unsigned int id, const LangString &text)
560 ok_->setEnabled(text[0]!='\0');
561 favourites_->setEnabled(text[0]!='\0');
564 void NetworkSelectDialog::buttonDown(unsigned int id)
566 if (id == refresh_->getId())
568 if (ServerBrowser::instance()->getRefreshing())
570 stopRefresh();
572 else
574 startRefresh();
577 else if (id == ok_->getId())
579 GLWWindowManager::instance()->hideWindow(id_);
581 if (ipaddress_->getText()[0])
583 ClientParams::instance()->reset();
584 ClientParams::instance()->setConnect(ipaddress_->getText().c_str());
585 ClientMain::startClient();
588 else if (id == favourites_->getId())
590 if (!ipaddress_->getText().empty())
592 std::set<std::string> favs =
593 ServerBrowser::instance()->getCollect().getFavourites();
595 if (refreshType_->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites")))
597 favs.erase(ipaddress_->getText().c_str());
599 else
601 favs.insert(ipaddress_->getText().c_str());
603 ServerBrowser::instance()->getCollect().setFavourites(favs);
605 if (refreshType_->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites")))
607 startRefresh();
611 else if (id == cancelId_)
613 GLWWindowManager::instance()->hideWindow(id_);