1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
4 // This file is part of Scorched3D.
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>
37 GLWIconTable::Column col
;
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), ""
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), ""
68 NetworkSelectDialog
*NetworkSelectDialog::instance_
= 0;
70 NetworkSelectDialog
*NetworkSelectDialog::instance()
74 instance_
= new NetworkSelectDialog
;
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),
86 std::list
<GLWIconTable::Column
> gamescolumns
, playerscolumns
;
89 if (getGamesCols()[i
].col
.width
== -1) break;
90 gamescolumns
.push_back(getGamesCols()[i
].col
);
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
)
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
);
160 glTexCoord2f(0.0f
, 0.0f
);
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
);
170 if (GLWToolTip::instance()->addToolTip(&colToolTip_
,
171 GLWTranslate::getPosX() + x
,
172 GLWTranslate::getPosY() + y
,
175 colToolTip_
.setText(ToolTip::ToolTipInfo
,
176 LANG_RESOURCE("STATUS_ICON", "Status Icon"), message
);
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
;
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
;
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
;
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
;
231 LANG_RESOURCE_CONST_VAR(CANNOT_CONTACT_SERVER
,
232 "CANNOT_CONTACT_SERVER", "Cannot contact server.");
233 message
= &CANNOT_CONTACT_SERVER
;
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())
252 std::string value
, tipValue
;
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"),
276 cogTex_
= TextureStore::instance()->loadTexture(
277 S3D::getDataFile("data/windows/cog.bmp"),
278 S3D::getDataFile("data/windows/coga.bmp"),
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
);
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
);
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");
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())));
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
++)
346 ServerBrowser::instance()->getServerList().getEntryValue(
347 row
, S3D::formatStringBuffer("pn%i", i
));
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());
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");
370 Vector
color(0.3f
, 0.3f
, 0.3f
);
371 GLWFont::instance()->getGameFont()->drawWidth(w
,
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
,
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())
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
,
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()))
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())
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()
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"));
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"));
530 favourites_
->setText(LANG_RESOURCE("ADD_FAVOURITE", "Add Favourite"));
536 void NetworkSelectDialog::startRefresh()
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
);
552 void NetworkSelectDialog::stopRefresh()
554 ServerBrowser::instance()->cancel();
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())
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());
601 favs
.insert(ipaddress_
->getText().c_str());
603 ServerBrowser::instance()->getCollect().setFavourites(favs
);
605 if (refreshType_
->isSelected(LANG_RESOURCE("FAVOURITES", "Favourites")))
611 else if (id
== cancelId_
)
613 GLWWindowManager::instance()->hideWindow(id_
);