1 /////////////////////////////////////////
2 //
3 // OpenLieroX
4 //
5 // code under LGPL, based on JasonBs work,
6 // enhanced by Dark Charlie and Albert Zeyer
7 //
8 //
9 /////////////////////////////////////////
10
11
12 // Net menu - Joining
13 // Created 25/8/02
14 // Jason Boettcher
15
16
17
18
19 #include "LieroX.h"
20 #include "Sounds.h"
21 #include "CClient.h"
22 #include "DeprecatedGUI/Graphics.h"
23 #include "DeprecatedGUI/Menu.h"
24 #include "GfxPrimitives.h"
25 #include "StringUtils.h"
26 #include "CWorm.h"
27 #include "Protocol.h"
28 #include "DeprecatedGUI/CButton.h"
29 #include "DeprecatedGUI/CTextbox.h"
30 #include "DeprecatedGUI/CImage.h"
31 #include "DeprecatedGUI/CCheckbox.h"
32 #include "DeprecatedGUI/CLabel.h"
33 #include "DeprecatedGUI/CTextButton.h"
34 #include "DeprecatedGUI/CProgressbar.h"
35 #include "DeprecatedGUI/CBrowser.h"
36 #include "AuxLib.h"
37 #include "CClientNetEngine.h"
38 #include "Debug.h"
39 #include "console.h"
40 #include "DeprecatedGUI/CChatWidget.h"
41
42
43 namespace DeprecatedGUI {
44
45 /*
46 Joining is broken into 2 parts:
47 1) Joining the server
48 2) If we succeeded in join, the lobby
49 */
50
51
52 // Joining menu's
53 enum {
54 //join_players=0,
55 join_connecting=0,
56 join_lobby
57 };
58
59 int iJoinMenu = join_connecting;
60 std::string sJoinAddress;
61
62
63 ///////////////////
64 // Join a server
Menu_Net_JoinInitialize(const std::string & sAddress)65 bool Menu_Net_JoinInitialize(const std::string& sAddress)
66 {
67 iNetMode = net_join;
68 iJoinMenu = join_connecting;
69 sJoinAddress = sAddress;
70
71 if(!Menu_Net_JoinConnectionInitialize(sAddress)) {
72 // Error
73 return false;
74 }
75
76
77 return true;
78 }
79
80
81 ///////////////////
82 // Main join frame
Menu_Net_JoinFrame(int mouse)83 void Menu_Net_JoinFrame(int mouse)
84 {
85 switch(iJoinMenu) {
86
87 // Select players
88 /* case join_players:
89 Menu_Net_JoinPlayersFrame(mouse);
90 break;*/
91
92 // Connecting
93 case join_connecting:
94 Menu_Net_JoinConnectionFrame(mouse);
95 break;
96
97 // Lobby
98 case join_lobby:
99 Menu_Net_JoinLobbyFrame(mouse);
100 break;
101 }
102 }
103
Menu_Net_JoinShutdown()104 void Menu_Net_JoinShutdown()
105 {
106 Menu_Net_JoinConnectionShutdown();
107 Menu_Net_JoinLobbyShutdown();
108 }
109
110
111
112
113
114
115 /*
116
117 Connect to the server
118
119 */
120
121
122 static CGuiLayout cConnecting;
123 static Timer *cConnectingScreenUpdate = NULL;
124
125 enum {
126 cm_Cancel=0
127 };
128
129
130 ///////////////////
131 // Initialize the connection menu
Menu_Net_JoinConnectionInitialize(const std::string & sAddress)132 bool Menu_Net_JoinConnectionInitialize(const std::string& sAddress)
133 {
134 iJoinMenu = join_connecting;
135 tLX->iGameType = GME_JOIN;
136 sJoinAddress = sAddress;
137 cConnecting.Shutdown();
138 cConnecting.Initialize();
139
140 cConnecting.Add( new CButton(BUT_CANCEL, tMenu->bmpButtons), cm_Cancel, 25, 440, 75,15);
141
142 Menu_redrawBufferRect(0, 0, 640, 480);
143 if (!cConnectingScreenUpdate)
144 cConnectingScreenUpdate = new Timer("Connecting...", null, NULL, 250, false);
145 cConnectingScreenUpdate->start();
146
147 return true;
148 }
149
Menu_Net_JoinConnectionShutdown()150 void Menu_Net_JoinConnectionShutdown()
151 {
152 cConnectingScreenUpdate->stop();
153 cConnecting.Shutdown();
154 }
155
156
157 ///////////////////
158 // Connection frame
Menu_Net_JoinConnectionFrame(int mouse)159 void Menu_Net_JoinConnectionFrame(int mouse)
160 {
161 gui_event_t *ev = NULL;
162
163 Menu_redrawBufferRect(0,180,640,tLX->cFont.GetHeight());
164
165 // Process the client frame
166 tLX->cFont.DrawCentre(VideoPostProcessor::videoSurface(), 320, 180, tLX->clNormalLabel, "Connecting to " + cClient->getServerAddr_HumanReadable());
167 cClient->Frame();
168
169
170 // Connected??
171 if(cClient->getStatus() == NET_CONNECTED) {
172
173 // Leave this connection screen & go to the lobby
174 Menu_Net_JoinConnectionShutdown();
175
176 if(!Menu_Net_JoinLobbyInitialize()) {
177 // Error
178 Menu_Net_MainInitialize();
179 }
180 return;
181 }
182
183 // Check for a bad connection
184 if(cClient->getBadConnection()) {
185 warnings << "Bad connection: " << cClient->getBadConnectionMsg() << endl;
186 Menu_MessageBox("Connection Error", cClient->getBadConnectionMsg(), LMB_OK);
187
188 cClient->Shutdown();
189
190 // Shutdown
191 Menu_Net_JoinConnectionShutdown();
192 Menu_NetInitialize();
193 return;
194 }
195
196
197 // Process & Draw the gui
198 ev = cConnecting.Process();
199 cConnecting.Draw( VideoPostProcessor::videoSurface() );
200
201
202 // Process any events
203 if(ev) {
204
205 switch(ev->iControlID) {
206
207 // Cancel
208 case cm_Cancel:
209 if(ev->iEventMsg == BTN_CLICKED) {
210
211 // Click!
212 PlaySoundSample(sfxGeneral.smpClick);
213
214 // Shutdown
215 Menu_Net_JoinConnectionShutdown();
216
217 Menu_NetInitialize();
218 }
219 break;
220 }
221 }
222
223
224 // Draw the mouse
225 DrawCursor(VideoPostProcessor::videoSurface());
226 }
227
228
229
230
231
232
233
234 /*
235
236 Join lobby
237
238 */
239
240 CGuiLayout cJoinLobby;
241 int iJoinSpeaking = 0;
242 bool bJoin_Update = true;
243 enum {
244 jl_Back=0,
245 jl_Ready,
246 jl_ChatText,
247 jl_ChatList,
248 jl_Favourites,
249 jl_PlayerList,
250 jl_Details,
251 jl_CancelDownload,
252 jl_DownloadProgress,
253 jl_DownloadMap,
254 jl_DownloadMod,
255 jl_More,
256 jl_Less
257 };
258
259
260
261 ///////////////////
262 // Initialize the joining lobby
Menu_Net_JoinLobbyInitialize()263 bool Menu_Net_JoinLobbyInitialize()
264 {
265 Menu_Net_JoinDrawLobby();
266
267 Menu_Net_JoinLobbyCreateGui();
268
269 // Add the chat
270 CBrowser *lv = (CBrowser *)cJoinLobby.getWidget(jl_ChatList);
271 if (lv) {
272 lv->InitializeChatBox();
273 CChatBox *Chatbox = cClient->getChatbox();
274 lines_iterator it = Chatbox->Begin();
275
276 // Copy the chat text
277 for ( ; it != Chatbox->End(); it++ ) {
278 lv->AddChatBoxLine(it->strLine, it->iColour, it->iTextType);
279 }
280 }
281
282 iNetMode = net_join;
283 iJoinMenu = join_lobby;
284
285 cClient->getChatbox()->Clear();
286 iJoinSpeaking = 0; // The first player is always speaking
287 tMenu->sSavedChatText = "";
288
289 tLX->iGameType = GME_JOIN;
290
291 return true;
292 }
293
294 ////////////////////
295 // Shutdown the join lobby
Menu_Net_JoinLobbyShutdown()296 void Menu_Net_JoinLobbyShutdown()
297 {
298 if (cClient)
299 cClient->Disconnect();
300
301 cJoinLobby.Shutdown();
302
303 if (cClient)
304 cClient->Shutdown();
305
306 tMenu->sSavedChatText = "";
307 }
308
309
310 ///////////////////
311 // Draw the join lobby
Menu_Net_JoinDrawLobby()312 void Menu_Net_JoinDrawLobby()
313 {
314 // Create the buffer
315 DrawImage(tMenu->bmpBuffer.get(),tMenu->bmpMainBack_common,0,0);
316 if (tMenu->tFrontendInfo.bPageBoxes)
317 Menu_DrawBox(tMenu->bmpBuffer.get(), 5,5, 635, 475);
318
319 // Title
320 DrawImageAdv(tMenu->bmpBuffer.get(), tMenu->bmpMainBack_common, 281,0, 281,0, 79,20);
321 tLX->cFont.DrawCentre(tMenu->bmpBuffer.get(), 320, -1, tLX->clNormalLabel, "[ Lobby ]");
322
323 // Chat box
324 DrawRectFill(tMenu->bmpBuffer.get(), 16, 270, 624, 417, tLX->clChatBoxBackground);
325
326 Menu_RedrawMouse(true);
327 }
328
329 static void updateDetailsList(CListview* l);
330
initDetailsList(CListview * l)331 static void initDetailsList(CListview* l) {
332 #define SUBS(title) l->AddSubitem(LVS_TEXT, title, (DynDrawIntf*)NULL, NULL); l->AddSubitem(LVS_TEXT, "", (DynDrawIntf*)NULL, NULL);
333 int index = 0;
334 l->Clear();
335 l->AddItem("servername", index++, tLX->clNormalLabel); SUBS("Server name:");
336 l->AddItem("level", index++, tLX->clNormalLabel); SUBS("Level:");
337 if (tMenu->bmpDownload.get()) {
338 CImage *img = new CImage(tMenu->bmpDownload);
339 img->Setup(jl_DownloadMap, 0, 0, img->getWidth(), img->getHeight());
340 l->AddSubitem(LVS_WIDGET, "", (DynDrawIntf*)NULL, img);
341 }
342 l->AddItem("gamemode", index++, tLX->clNormalLabel); SUBS("Game Mode:");
343 l->AddItem("mod", index++, tLX->clNormalLabel); SUBS("Mod:");
344 if (tMenu->bmpDownload.get()) {
345 CImage *img = new CImage(tMenu->bmpDownload);
346 img->Setup(jl_DownloadMod, 0, 0, img->getWidth(), img->getHeight());
347 l->AddSubitem(LVS_WIDGET, "", (DynDrawIntf*)NULL, img);
348 }
349 l->AddItem("lives", index++, tLX->clNormalLabel); SUBS("Lives:");
350 l->AddItem("maxkills", index++, tLX->clNormalLabel); SUBS("Max Kills:");
351 l->AddItem("timelimit", index++, tLX->clNormalLabel); SUBS("Timelimit:");
352 l->AddItem("loadingtime", index++, tLX->clNormalLabel); SUBS("Loading time:");
353 l->AddItem("bonuses", index++, tLX->clNormalLabel); SUBS("Bonuses:");
354
355 if (tLXOptions->bAdvancedLobby) {
356 l->AddItem("serverversion", index++, tLX->clNormalLabel); SUBS("Server version:");
357 } else {
358 // More button
359 lv_item_t *it = l->AddItem("more", index++, tLX->clNormalLabel);
360 l->AddSubitem(LVS_TEXT, "", (DynDrawIntf*)NULL, NULL);
361 CButton *more = new CButton(BUT_MORE, tMenu->bmpButtons);
362 more->setID(jl_More);
363 more->Create();
364 it->iHeight = more->getHeight() + 10;
365 l->AddSubitem(LVS_WIDGET, "", (DynDrawIntf*)NULL, more);
366 }
367 #undef SUBS
368 updateDetailsList(l);
369 }
370
updateDetailsList(CListview * l)371 static void updateDetailsList(CListview* l) {
372 #define SETI { i = l->getItem(index++); si = i->tSubitems->tNext; si->iColour = defaultColor; }
373 int index = 0;
374 lv_item_t* i;
375 lv_subitem_t* si;
376 l->SaveScrollbarPos();
377 Color defaultColor = tLX->clPrivateText;
378 SETI; si->sText = cClient->getServerName(); // servername
379 SETI;
380 if(cClient->getHaveMap()) {
381 si->sText = cClient->getGameLobby()->sMapName;
382 if (si->tNext)
383 si->tNext->bVisible = false; // Hide the download button
384 } else { // Don't have the map
385 si->sText = cClient->getGameLobby()->sMapFile;
386 si->iColour = tLX->clError;
387 if (si->tNext) {
388 // not downloading the map, display an option for doing so
389 si->tNext->bVisible = !cClient->getDownloadingMap();
390 }
391 }
392
393 const std::string gamemodes[] = {"Death Match","Team Death Match", "Tag", "Demolitions"};
394 SETI;
395 if(cClient->getGameLobby()->sGameMode == "") {
396 int generalType = cClient->getGameLobby()->iGeneralGameType;
397 si->sText = (generalType < 0 || (uint)generalType >= sizeof(gamemodes)/sizeof(std::string)) ? "Invalid" : gamemodes[generalType];
398 } else
399 si->sText = cClient->getGameLobby()->sGameMode;
400 SETI;
401 if(cClient->getHaveMod()) {
402 si->sText = cClient->getGameLobby()->sModName;
403 if (si->tNext)
404 si->tNext->bVisible = false; // Hide the download button
405 } else {
406 si->sText = cClient->getGameLobby()->sModName;
407 si->iColour = tLX->clError;
408 if (si->tNext)
409 si->tNext->bVisible = !cClient->getDownloadingMod();
410 }
411
412 SETI;
413 if(cClient->getGameLobby()->iLives >= 0) {
414 si->sText = itoa(cClient->getGameLobby()->iLives);
415 } else {
416 si->sText = "infinity";
417 si->iColour = tLX->clDisabled;
418 }
419
420 SETI;
421 if(cClient->getGameLobby()->iKillLimit >= 0) {
422 si->sText = itoa(cClient->getGameLobby()->iKillLimit);
423 } else {
424 si->sText = "infinity";
425 si->iColour = tLX->clDisabled;
426 }
427
428 SETI;
429 if(cClient->getGameLobby()->fTimeLimit >= 0) {
430 si->sText = ftoa(cClient->getGameLobby()->fTimeLimit) + " min";
431 } else if(cClient->getGameLobby()->fTimeLimit <= -100) {
432 si->sText = "unknown";
433 si->iColour = tLX->clDisabled;
434 } else {
435 si->sText = "disabled";
436 si->iColour = tLX->clDisabled;
437 }
438
439 SETI; si->sText = itoa(cClient->getGameLobby()->iLoadingTime) + "%";
440 SETI; si->sText = cClient->getGameLobby()->bBonusesOn ? "On" : "Off";
441
442 // Advanced info
443 if (tLXOptions->bAdvancedLobby) {
444 SETI; si->sText = cClient->getServerVersion().asString(); // serverversion
445
446 int numItems = l->getNumItems();
447 for( int rm = index; rm < numItems; rm++ )
448 l->RemoveItem(rm);
449
450 foreach( Feature*, f, Array(featureArray,featureArrayLen()) ) {
451 if( cClient->getGameLobby()->features[f->get()] == f->get()->unsetValue )
452 continue;
453 i = l->AddItem("feature:" + f->get()->name, index++, tLX->clNormalLabel);
454 l->AddSubitem(LVS_TEXT, f->get()->humanReadableName + ":", (DynDrawIntf*)NULL, NULL);
455 l->AddSubitem(LVS_TEXT, "", (DynDrawIntf*)NULL, NULL);
456 si = i->tSubitems->tNext;
457
458 si->iColour = defaultColor;
459 si->sText = cClient->getGameLobby()->features[f->get()].toString();
460 }
461
462 foreach( FeatureCompatibleSettingList::Feature&, f, cClient->getUnknownFeatures().list ) {
463 i = l->AddItem("feature:" + f->get().name, index++, tLX->clNormalLabel);
464 l->AddSubitem(LVS_TEXT, f->get().humanName + ":", (DynDrawIntf*)NULL, NULL);
465 l->AddSubitem(LVS_TEXT, "", (DynDrawIntf*)NULL, NULL);
466
467 si = i->tSubitems->tNext;
468 Color col;
469 switch(f->get().type) {
470 case FeatureCompatibleSettingList::Feature::FCSL_JUSTUNKNOWN: col = tLX->clDisabled; break;
471 case FeatureCompatibleSettingList::Feature::FCSL_INCOMPATIBLE: col = tLX->clError; break;
472 default: col = defaultColor;
473 }
474 si->iColour = col;
475 si->sText = f->get().var.toString();
476 }
477
478 // Less button
479 lv_item_t *it = l->AddItem("less", index++, tLX->clNormalLabel);
480 l->AddSubitem(LVS_TEXT, "", (DynDrawIntf*)NULL, NULL);
481 CButton *less = new CButton(BUT_LESS, tMenu->bmpButtons);
482 less->setID(jl_Less);
483 less->Create();
484 it->iHeight = less->getHeight() + 10;
485 l->AddSubitem(LVS_WIDGET, "", (DynDrawIntf*)NULL, less);
486 }
487
488 l->RestoreScrollbarPos();
489
490 #undef SETI
491 }
492
493 ////////////////////
494 // Finished the mod/map download (callback)
Menu_Net_JoinDlFinished()495 void Menu_Net_JoinDlFinished()
496 {
497 CButton *cancel = (CButton *)cJoinLobby.getWidget(jl_CancelDownload);
498 CProgressBar *progress = (CProgressBar *)cJoinLobby.getWidget(jl_DownloadProgress);
499 CListview *details = (CListview *)cJoinLobby.getWidget(jl_Details);
500 if (!cancel || !progress || !details)
501 return;
502
503 updateDetailsList(details);
504
505 // If we are still downloading, don't hide the progress
506 if (cClient->getDownloadingMap() || cClient->getDownloadingMod())
507 return;
508
509 // Hide the progress
510 details->Setup(details->getID(), details->getX(), details->getY(), details->getWidth(), 250);
511 details->ReadjustScrollbar();
512
513 progress->setEnabled(false);
514 cancel->setEnabled(false);
515 }
516
517 ////////////////////
518 // Changes the GUI to display downloading things
Menu_Net_JoinStartDownload()519 void Menu_Net_JoinStartDownload()
520 {
521 CButton *cancel = (CButton *)cJoinLobby.getWidget(jl_CancelDownload);
522 CProgressBar *progress = (CProgressBar *)cJoinLobby.getWidget(jl_DownloadProgress);
523 CListview *details = (CListview *)cJoinLobby.getWidget(jl_Details);
524 if (!cancel || !progress || !details)
525 return;
526
527 // Show the progress
528 details->Setup(details->getID(), details->getX(), details->getY(), details->getWidth(), 210);
529 details->ReadjustScrollbar();
530
531 progress->setEnabled(true);
532 cancel->setEnabled(true);
533 }
534
535
536 ///////////////////
537 // Create the lobby gui stuff
Menu_Net_JoinLobbyCreateGui()538 void Menu_Net_JoinLobbyCreateGui()
539 {
540 cJoinLobby.Shutdown();
541 cJoinLobby.Initialize();
542
543 cJoinLobby.Add( new CButton(BUT_LEAVE, tMenu->bmpButtons),jl_Back, 15, 450, 60, 15);
544 cJoinLobby.Add( new CButton(BUT_READY, tMenu->bmpButtons),jl_Ready, 560, 450, 65, 15);
545 cJoinLobby.Add( new CButton(BUT_ADDTOFAVOURITES, tMenu->bmpButtons), jl_Favourites, 230,450,150,15);
546 cJoinLobby.Add( new CTextbox(), jl_ChatText, 15, 421, 610, tLX->cFont.GetHeight());
547 cJoinLobby.Add( new CBrowser(), jl_ChatList, 15, 268, 610, 150);
548 cJoinLobby.Add( new CListview(), jl_PlayerList, 15, 15, 325, 220);
549 cJoinLobby.Add( new CListview(), jl_Details, 350, 15, 290, 250);
550
551 // Downloading stuff
552 CProgressBar *dl = new CProgressBar(LoadGameImage("data/frontend/downloadbar_lobby.png", true), 0, 0, false, 1);
553 CButton *cancel = new CButton(BUT_CANCEL, tMenu->bmpButtons);
554 cJoinLobby.Add( dl, jl_DownloadProgress, 360, 245, 0, 0);
555 cJoinLobby.Add( cancel, jl_CancelDownload, 360 + dl->getWidth() + 5, 245 + (dl->getHeight() - 20)/2, 0, 0);
556 dl->setEnabled(false);
557 cancel->setEnabled(false);
558 cClient->setOnMapDlFinished(&Menu_Net_JoinDlFinished);
559 cClient->setOnModDlFinished(&Menu_Net_JoinDlFinished);
560
561 // Setup the player list
562 CListview *player_list = (CListview *)cJoinLobby.getWidget(jl_PlayerList);
563 if (player_list) {
564 player_list->setShowSelect(false);
565 player_list->setOldStyle(true);
566 player_list->AddColumn("Players", tMenu->bmpLobbyReady.get()->w + 2, tLX->clHeading); // Lobby ready/Players label
567 player_list->AddColumn("", 30); // Skin
568 player_list->AddColumn("", 220); // Name
569 player_list->AddColumn("", -1); // Team
570 }
571
572
573 CListview* details = (CListview *)cJoinLobby.getWidget(jl_Details);
574 //details->Setup(0, x + 15, y+5, w - 30, h - 25); // is this done already in .Add(...) above?
575 details->setDrawBorder(false);
576 details->setRedrawMenu(false);
577 details->setShowSelect(false);
578 details->setOldStyle(true);
579 details->subItemsAreAligned() = true;
580
581 // like in Menu_SvrList_DrawInfo
582 int first_column_width = tLX->cFont.GetWidth("Loading Times:") + 30; // Width of the widest item in this column + some space
583 int last_column_width = tLX->cFont.GetWidth("999"); // Kills width
584 details->AddColumn("", first_column_width);
585 details->AddColumn("", details->getWidth() - first_column_width - (last_column_width*2) - gfxGUI.bmpScrollbar.get()->w); // The rest
586 details->AddColumn("", last_column_width);
587 details->AddColumn("", last_column_width);
588
589 initDetailsList(details);
590
591 iJoinSpeaking = 0; // The first client is always speaking
592
593 cJoinLobby.FocusWidget(jl_ChatText);
594 #ifdef __ANDROID__
595 Menu_WarpMouse(cJoinLobby.getWidget(jl_ChatText)->getX() + cJoinLobby.getWidget(jl_ChatText)->getWidth() - 2,
596 cJoinLobby.getWidget(jl_ChatText)->getY() + cJoinLobby.getWidget(jl_ChatText)->getHeight() - 2);
597 #endif
598 }
599
600
601 ///////////////////
602 // Go straight back to the join lobby
603 // TODO: please comment the difference between Menu_Net_JoinGotoLobby and GotoJoinLobby
Menu_Net_JoinGotoLobby()604 void Menu_Net_JoinGotoLobby()
605 {
606 Menu_Net_JoinDrawLobby();
607
608 Menu_Net_JoinLobbyCreateGui();
609
610 iNetMode = net_join;
611 iJoinMenu = join_lobby;
612
613 // Add the chat
614 CBrowser *lv = (CBrowser *)cJoinLobby.getWidget(jl_ChatList);
615 if (lv) {
616 lv->InitializeChatBox();
617 CChatBox *Chatbox = cClient->getChatbox();
618 lines_iterator it = Chatbox->At((int)Chatbox->getNumLines()-256); // If there's more than 256 messages, we start not from beginning but from end()-256
619 //int id = (lv->getLastItem() && lv->getItems()) ? lv->getLastItem()->iIndex + 1 : 0;
620
621 // Copy the chat text
622 for (; it != Chatbox->End(); it++) {
623 if (it->iTextType == TXT_CHAT || it->iTextType == TXT_PRIVATE || it->iTextType == TXT_TEAMPM) { // Add only chat messages
624 lv->AddChatBoxLine(it->strLine, it->iColour, it->iTextType);
625 }
626 }
627 }
628
629 // Add the ingame chatter text to lobby chatter
630 Menu_Net_JoinLobbySetText(cClient->chatterText());
631
632 iJoinSpeaking = 0; // The first player is always speaking
633 tMenu->sSavedChatText = "";
634 }
635
636 //////////////////////
637 // Get the content of the chatbox
Menu_Net_JoinLobbyGetText()638 std::string Menu_Net_JoinLobbyGetText()
639 {
640 if (tMenu->bMenuRunning) {
641 std::string buf;
642 cJoinLobby.SendMessage(jl_ChatText, TXS_GETTEXT, &buf, 256);
643 return buf;
644 } else {
645 return tMenu->sSavedChatText;
646 }
647 }
648
Menu_Net_JoinLobbySetText(const std::string & str)649 void Menu_Net_JoinLobbySetText(const std::string& str) {
650 cJoinLobby.SendMessage(jl_ChatText, TXS_SETTEXT, str, 0);
651 }
652
653
654 ///////////////////
655 // Join lobby frame
Menu_Net_JoinLobbyFrame(int mouse)656 void Menu_Net_JoinLobbyFrame(int mouse)
657 {
658 gui_event_t *ev = NULL;
659 int i,y;
660
661 // Process the client
662 cClient->Frame();
663
664 // If there is a client error, leave
665 if(cClient->getClientError()) {
666
667 Menu_Net_JoinShutdown();
668 Menu_NetInitialize();
669 bJoin_Update = true;
670 return;
671 }
672
673
674 // If we have started, leave the frontend
675 if(cClient->getGameReady()) {
676
677 cJoinLobby.Shutdown();
678
679 // Setup the client
680 cClient->SetupViewports();
681
682 // Leave the frontend
683 *bGame = true;
684 tMenu->bMenuRunning = false;
685 tLX->iGameType = GME_JOIN;
686
687 // Save the chat text
688 cJoinLobby.SendMessage(jl_ChatText, TXS_GETTEXT, &tMenu->sSavedChatText, 256);
689
690 bJoin_Update = true;
691
692 return;
693 }
694
695
696 // Check if the communication link between us & server is still ok
697 if(cClient->getServerError()) {
698 // Create the buffer
699 DrawImage(tMenu->bmpBuffer.get(),tMenu->bmpMainBack_common,0,0);
700 Menu_DrawSubTitle(tMenu->bmpBuffer.get(),SUB_LOBBY);
701
702 Menu_MessageBox("Communication", cClient->getServerErrorMsg(), LMB_OK);
703
704 cJoinLobby.Shutdown();
705
706 Menu_NetInitialize();
707
708 bJoin_Update = true;
709 return;
710 }
711
712
713 // Clear the player list and game settings
714 Menu_redrawBufferRect(15, 15, 400, 230);
715 Menu_redrawBufferRect(360,15, 280, 200);
716
717
718 // Add chat to the listbox
719 CBrowser *lv = (CBrowser *)cJoinLobby.getWidget(jl_ChatList);
720 line_t ln;
721 while(cClient->getChatbox()->GetNewLine(ln)) {
722 lv->AddChatBoxLine(ln.strLine, ln.iColour, ln.iTextType);
723 }
724
725
726 // Downloading progress
727 if (cClient->getDownloadingMap() || cClient->getDownloadingMod()) {
728 CProgressBar *bar = (CProgressBar *)cJoinLobby.getWidget(jl_DownloadProgress);
729 if (bar)
730 bar->SetPosition(cClient->getDlProgress());
731 }
732
733
734 // Draw the connected players
735 if (bJoin_Update) {
736 CListview *player_list = (CListview *)cJoinLobby.getWidget(jl_PlayerList);
737 if (!player_list) { // Weird, shouldn't happen
738 warnings << "Menu_Net_JoinLobbyFrame: player_list unset" << endl;
739 return;
740 }
741 player_list->SaveScrollbarPos();
742 player_list->Clear(); // Clear first
743
744 CWorm *w = cClient->getRemoteWorms();
745 CImage *team_img = NULL;
746
747 for (i=0; i < MAX_PLAYERS; i++, w++) {
748 if (!w->isUsed()) // Don't bother with unused worms
749 continue;
750
751 w->ChangeGraphics(cClient->getGameLobby()->iGeneralGameType);
752
753 // Add the item
754 player_list->AddItem(w->getName(), i, tLX->clNormalLabel);
755 if (w->getLobbyReady()) // Ready control
756 player_list->AddSubitem(LVS_IMAGE, "", tMenu->bmpLobbyReady, NULL);
757 else
758 player_list->AddSubitem(LVS_IMAGE, "", tMenu->bmpLobbyNotReady, NULL);
759 player_list->AddSubitem(LVS_IMAGE, "", w->getPicimg(), NULL); // Skin
760 player_list->AddSubitem(LVS_TEXT, "#"+itoa(w->getID())+" "+w->getName(), (DynDrawIntf*)NULL, NULL); // Name
761
762 // Display the team mark if TDM
763 if (cClient->getGameLobby()->iGeneralGameType == GMT_TEAMS) {
764 team_img = new CImage(gfxGame.bmpTeamColours[w->getTeam()]);
765 if (!team_img)
766 continue;
767 team_img->setID(w->getID());
768 team_img->setRedrawMenu(false);
769
770 player_list->AddSubitem(LVS_WIDGET, "", (DynDrawIntf*)NULL, team_img); // Team
771 }
772 }
773
774 player_list->RestoreScrollbarPos(); // Scroll back to where we were before the update
775
776 CListview* details = (CListview *)cJoinLobby.getWidget(jl_Details);
777 updateDetailsList(details);
778
779 bJoin_Update = false;
780 }
781
782 // Draw the game info
783 if(true) { //if(GameLobby->bSet) {
784 CFont *f = &tLX->cFont;
785 int x = 360;
786 y = 15;
787
788 f->Draw(VideoPostProcessor::videoSurface(), x, y, tLX->clHeading, "Game Details");
789 }
790
791 // If any textbox is selected, forbid to show the console
792 if (cJoinLobby.getFocusedWidget() && !Con_IsVisible()) {
793 tMenu->bForbidConsole = cJoinLobby.getFocusedWidget()->getType() == wid_Textbox;
794 }
795
796 // Process & Draw the gui
797 if (!Con_IsVisible() && !CChatWidget::GlobalEnabled()) // Don't process when the console is opened
798 ev = cJoinLobby.Process();
799
800 cJoinLobby.Draw( VideoPostProcessor::videoSurface() );
801
802 if(CChatWidget::GlobalEnabled())
803 {
804 CChatWidget::GlobalProcessAndDraw(VideoPostProcessor::videoSurface());
805 return;
806 }
807
808 // Process any events
809 if(ev) {
810 switch(ev->iControlID) {
811
812 // Back
813 case jl_Back:
814 if(ev->iEventMsg == BTN_CLICKED) {
815 // Click
816 PlaySoundSample(sfxGeneral.smpClick);
817
818 Menu_Net_JoinLobbyShutdown();
819
820 // Back to net menu
821 Menu_NetInitialize();
822 }
823 break;
824
825 // Ready
826 case jl_Ready:
827 if(ev->iEventMsg == BTN_CLICKED) {
828 // Let the server know that my worms are now ready
829 bool ready = true;
830 if( cClient->getNumWorms() > 0 )
831 ready = ! cClient->getWorm(0)->getLobbyReady();
832 cClient->getNetEngine()->SendUpdateLobby(ready);
833
834 // Hide the ready button
835 /*
836 CButton *btn = (CButton *)cJoinLobby.getWidget(jl_Ready);
837 btn->setEnabled(false);
838 btn->redrawBuffer();
839 */
840 }
841 break;
842
843 // Add to favourites
844 case jl_Favourites:
845 if (ev->iEventMsg == BTN_CLICKED) {
846 Menu_SvrList_AddFavourite(cClient->getServerName(),cClient->getServerAddress());
847 }
848 break;
849
850 // Cancel file transfers
851 case jl_CancelDownload:
852 if (ev->iEventMsg == BTN_CLICKED) {
853 cClient->AbortDownloads();
854 }
855 break;
856
857 // Chat box
858 case jl_ChatList:
859 if (ev->iEventMsg == BRW_KEY_NOT_PROCESSED) {
860 // Activate the textbox automatically
861 cJoinLobby.FocusWidget(jl_ChatText);
862 tMenu->bForbidConsole = true;
863
864 // Hack: add the just-pressed key to the textbox
865 CTextbox *txt = (CTextbox *)cJoinLobby.getWidget(jl_ChatText);
866 if (txt && GetKeyboard()->queueLength > 0) {
867 KeyboardEvent kbev = GetKeyboard()->keyQueue[GetKeyboard()->queueLength - 1];
868 txt->KeyDown(kbev.ch, kbev.sym, *GetCurrentModstate());
869 }
870 }
871 break;
872
873
874 // Chat textbox
875 case jl_ChatText:
876 if(ev->iEventMsg == TXT_ENTER && iJoinSpeaking >= 0) {
877 // Send the msg to the server
878
879 // Get the text
880 std::string text;
881 cJoinLobby.SendMessage(jl_ChatText, TXS_GETTEXT, &text, 0);
882
883 // Don't send empty messages
884 if(text.size() == 0)
885 break;
886
887 // Clear the text box
888 cJoinLobby.SendMessage(jl_ChatText, TXS_SETTEXT, "",0);
889
890 // Send
891 cClient->getNetEngine()->SendText(text, cClient->getWorm(0)->getName());
892 } else
893 if(ev->iEventMsg == TXT_TAB) {
894 if(strSeemsLikeChatCommand(Menu_Net_JoinLobbyGetText())) {
895 cClient->getNetEngine()->SendChatCommandCompletionRequest(Menu_Net_JoinLobbyGetText().substr(1));
896 return;
897 }
898 }
899 break;
900
901 case jl_Details:
902 if (ev->iEventMsg == LV_WIDGETEVENT) {
903 CListview *details = (CListview *)cJoinLobby.getWidget(jl_Details);
904 gui_event_t *ev2 = details->getWidgetEvent();
905 if (ev2) {
906 switch (ev2->iControlID) {
907 case jl_DownloadMap:
908 if (ev2->iEventMsg == IMG_CLICK) {
909 cClient->DownloadMap(cClient->getGameLobby()->sMapFile); // Download the map
910 Menu_Net_JoinStartDownload();
911 updateDetailsList(details);
912 }
913 break;
914 case jl_DownloadMod:
915 if (ev2->iEventMsg == IMG_CLICK) {
916 cClient->DownloadMod(cClient->getGameLobby()->sModDir); // Download the mod
917 Menu_Net_JoinStartDownload();
918 updateDetailsList(details);
919 }
920 break;
921 case jl_Less:
922 if (ev2->iEventMsg == BTN_CLICKED) {
923 tLXOptions->bAdvancedLobby = false;
924 initDetailsList(details);
925 }
926 break;
927 case jl_More:
928 if (ev2->iEventMsg == BTN_CLICKED) {
929 tLXOptions->bAdvancedLobby = true;
930 initDetailsList(details);
931 }
932 break;
933 }
934 }
935 }
936 break;
937
938 /*case jl_StartStopUdpFileDownload:
939 if(ev->iEventMsg == TXB_MOUSEUP) {
940 if( cClient->getUdpFileDownloader()->getFilesPendingAmount() > 0 )
941 {
942 cClient->AbortMapDownloads();
943 if( ! cClient->getUdpFileDownloader()->isFinished() ||
944 cClient->getUdpFileDownloader()->getFilesPendingAmount() > 0 )
945 {
946 cClient->getUdpFileDownloader()->abortDownload();
947 cClient->getNetEngine()->SendFileData();
948 cClient->setLastFileRequest( tLX->currentTime + 10000.0f ); // Disable file download for current session
949 }
950 }
951 else
952 {
953 cClient->setLastFileRequest( tLX->currentTime - 10.0f ); // Re-enable file requests
954 if( ! cClient->getGameLobby()->bHaveMod && cClient->getGameLobby()->szModDir != "" )
955 cClient->getUdpFileDownloader()->requestFileInfo(cClient->getGameLobby()->szModDir, true);
956 if( ! cClient->getGameLobby()->bHaveMap && cClient->getGameLobby()->szMapFile != "" )
957 cClient->DownloadMap(cClient->getGameLobby()->szMapFile); // Download map with HTTP, then try UDP
958 }
959 }
960 break;*/
961 }
962 }
963
964 // Draw the mouse
965 DrawCursor(VideoPostProcessor::videoSurface());
966 }
967
968 }; // namespace DeprecatedGUI
969