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 - Internet
13 // Created 29/12/02
14 // Jason Boettcher
15 
16 
17 #include "LieroX.h"
18 #include "Sounds.h"
19 #include "Clipboard.h"
20 #include "AuxLib.h"
21 #include "HTTP.h"
22 #include "DeprecatedGUI/Graphics.h"
23 #include "CClient.h"
24 #include "DeprecatedGUI/Menu.h"
25 #include "GfxPrimitives.h"
26 #include "FindFile.h"
27 #include "StringUtils.h"
28 #include "DeprecatedGUI/CButton.h"
29 #include "DeprecatedGUI/CListview.h"
30 #include "DeprecatedGUI/CLabel.h"
31 #include "DeprecatedGUI/CCombobox.h"
32 #include "DeprecatedGUI/CMenu.h"
33 #include "DeprecatedGUI/CTextbox.h"
34 #include "DeprecatedGUI/CChatWidget.h"
35 #include "ProfileSystem.h"
36 #include "IpToCountryDB.h"
37 #include "Debug.h"
38 
39 
40 
41 
42 namespace DeprecatedGUI {
43 
44 CGuiLayout	cInternet;
45 std::string szNetCurServer;
46 
47 // Internet widgets
48 enum {
49 	mi_Join=0,
50 	mi_ServerList,
51 	mi_Refresh,
52 	mi_UpdateList,
53 	mi_AddServer,
54 	mi_Back,
55     mi_PopupMenu,
56 	mi_PlayerSelection,
57 };
58 
59 ///////////////////
60 // Initialize the Internet menu
Menu_Net_NETInitialize()61 bool Menu_Net_NETInitialize()
62 {
63 	iNetMode = net_internet;
64     szNetCurServer = "";
65 
66 	cInternet.Shutdown();
67 	cInternet.Initialize();
68 
69 	cInternet.Add( new CListview(),								mi_ServerList, 40, 180, 560, 242);
70 	cInternet.Add( new CButton(BUT_BACK, tMenu->bmpButtons),    mi_Back,       25, 440, 50,  15);
71 	cInternet.Add( new CButton(BUT_ADD, tMenu->bmpButtons),		mi_AddServer,  140,440, 40,  15);
72 	cInternet.Add( new CButton(BUT_REFRESH, tMenu->bmpButtons), mi_Refresh,	250,440, 83,  15);
73 	cInternet.Add( new CButton(BUT_UPDATELIST, tMenu->bmpButtons),	mi_UpdateList,  390,440, 125,  15);
74 	cInternet.Add( new CButton(BUT_JOIN, tMenu->bmpButtons),    mi_Join,		570,440, 43,  15);
75 	cInternet.Add( new CLabel("Select player:",tLX->clNormalLabel),-1,		125, 152, 180,15);
76 	cInternet.Add( new CCombobox(),								mi_PlayerSelection,		225,150, 170,  19);
77 	if( tLXOptions->bEnableChat && tLXOptions->bEnableMiniChat )
78 		cInternet.Add( new CChatWidget(),						-1,	25, 15, 585, 85 );
79 
80 	Menu_Net_AddTabBarButtons(&cInternet);
81 
82 	/*
83 	  Server list columns
84 
85       Connection speed
86 	  Name
87 	  State
88 	  Players
89 	  Ping
90 	  Address
91     */
92 
93 	// Add players to the list
94 	profile_t *p = GetProfiles();
95 	bool validName = false;
96 	for(;p;p=p->tNext) {
97 		/*if(p->iType == PRF_COMPUTER)
98 			continue;*/
99 
100 		int i = ((CCombobox*) cInternet.getWidget( mi_PlayerSelection ))->addItem(p->sName, p->sName);
101 		((CCombobox*) cInternet.getWidget( mi_PlayerSelection ))->setImage(p->cSkin.getPreview(), i);
102 		if( p->sName == tLXOptions->sLastSelectedPlayer )
103 			validName=true;
104 	}
105 
106 	if( ! validName )
107 		tLXOptions->sLastSelectedPlayer = GetProfiles()->sName;
108 
109 	((CCombobox*) cInternet.getWidget( mi_PlayerSelection ))->setCurSIndexItem( tLXOptions->sLastSelectedPlayer );
110 
111     Menu_redrawBufferRect(0, 0, 640, 480);
112 
113 	cInternet.SendMessage( mi_ServerList, LVS_ADDCOLUMN, "", tLXOptions->iInternetList[0]);
114 	cInternet.SendMessage( mi_ServerList, LVS_ADDCOLUMN, "Server Name", tLXOptions->iInternetList[1]);
115 	cInternet.SendMessage( mi_ServerList, LVS_ADDCOLUMN, "State", tLXOptions->iInternetList[2]);
116 	cInternet.SendMessage( mi_ServerList, LVS_ADDCOLUMN, "Players", tLXOptions->iInternetList[3]);
117 	cInternet.SendMessage( mi_ServerList, LVS_ADDCOLUMN, "Ping", tLXOptions->iInternetList[4]);
118 
119 	if (tLXOptions->bUseIpToCountry)
120 	{	// Too lazy to update tLXOptions, so I'll calculate last column width from width of listview
121 		//int CountryColumnWidth = 21; // TODO: not used
122 
123 		// HINT: because this column is optional, it is at the end of the array from options
124 		cInternet.SendMessage( mi_ServerList, LVS_ADDCOLUMN, "Country", tLXOptions->iInternetList[5]);
125 	}
126 
127 	cInternet.SendMessage( mi_ServerList, LVS_ADDCOLUMN, "Address", tLXOptions->iInternetList[6]);
128 
129 	((CListview*) cInternet.getWidget( mi_ServerList ))->SetSortColumn( tLXOptions->iInternetSortColumn, true ); // Sorting
130 
131 	// Clear the server list & grab an update
132 	Menu_SvrList_Clear();
133 
134     // Load the list
135     Menu_SvrList_LoadList("cfg/svrlist.dat");
136     Menu_SvrList_FillList( (CListview *)cInternet.getWidget( mi_ServerList ) );
137 	Menu_SvrList_UpdateUDPList();
138 
139 	Timer("Menu_Net_NETInitialize serverlist timeout", null, NULL, SVRLIST_TIMEOUT, true).startHeadless();
140 
141 	return true;
142 }
143 
144 
145 ///////////////////
146 // Shutdown the internet menu
Menu_Net_NETShutdown()147 void Menu_Net_NETShutdown()
148 {
149 	if (tLXOptions)  {
150 
151 		// Save the list
152 		if( iNetMode == net_internet )  {
153 			Menu_SvrList_SaveList("cfg/svrlist.dat");
154 
155 			CListview* l = (CListview *)cInternet.getWidget(mi_ServerList);
156 			if(l) {
157 				// Save the column widths
158 				for (int i=0;i<7;i++)
159 					tLXOptions->iInternetList[i] = l->GetColumnWidth(i);
160 
161 				// Save the sorting column
162 				tLXOptions->iInternetSortColumn = l->GetSortColumn();
163 			}
164 		}
165 
166 		// Save the selected player
167 		cb_item_t *item = (cb_item_t *)cInternet.SendMessage(mi_PlayerSelection,CBM_GETCURITEM,(DWORD)0,0); // TODO: 64bit unsafe (pointer cast)
168 		if (item)
169 			tLXOptions->sLastSelectedPlayer = item->sIndex;
170 	}
171 
172 	cInternet.Shutdown();
173 }
174 
175 
176 ///////////////////
177 // Net Internet frame
Menu_Net_NETFrame(int mouse)178 void Menu_Net_NETFrame(int mouse)
179 {
180 	gui_event_t *ev = NULL;
181 	std::string	addr;
182 
183 
184 	// Process & Draw the gui
185 	ev = cInternet.Process();
186 	cInternet.Draw( VideoPostProcessor::videoSurface() );
187 
188 	if (Menu_Net_ProcessTabBarButtons(ev))
189 		return;
190 
191 	// Process the server list
192 	static bool wasLoadedBefore = false;
193 	if( Menu_SvrList_Process() || (tIpToCountryDB->Loaded() && !wasLoadedBefore) ) {
194 		// Add the servers to the listview
195 		Menu_SvrList_FillList( (CListview *)cInternet.getWidget( mi_ServerList ) );
196 		wasLoadedBefore = tIpToCountryDB->Loaded();
197 	}
198 
199 
200 
201 	// Process any events
202 	if(ev) {
203 
204 		switch(ev->iControlID) {
205 
206 			// Add Server
207 			case mi_AddServer:
208 				if(ev->iEventMsg == BTN_CLICKED) {
209 					// Click!
210 					PlaySoundSample(sfxGeneral.smpClick);
211 
212 					Menu_Net_NETAddServer();
213 				}
214 				break;
215 
216 			// Back
217 			case mi_Back:
218 				if(ev->iEventMsg == BTN_CLICKED) {
219 
220 					// Shutdown
221 					Menu_Net_NETShutdown();
222 
223 					// Click!
224 					PlaySoundSample(sfxGeneral.smpClick);
225 
226 					// Back to main menu
227 					Menu_MainInitialize();
228 				}
229 				break;
230 
231 			// Refresh
232 			case mi_Refresh:
233 				if(ev->iEventMsg == BTN_CLICKED) {
234 
235 					// Click!
236 					PlaySoundSample(sfxGeneral.smpClick);
237 
238 					// Refresh the currently visible servers
239 					Menu_SvrList_RefreshList();
240 					Menu_SvrList_FillList( (CListview *)cInternet.getWidget( mi_ServerList ) );
241 				}
242 				break;
243 
244 			// Join
245 			case mi_Join:
246                 if(ev->iEventMsg == BTN_CLICKED) {
247 
248 					addr = "";
249 					int result = cInternet.SendMessage(mi_ServerList, LVS_GETCURSINDEX, &addr, 0);
250 					if(result != -1 && addr != "") {
251 
252                         // Save the list
253                         Menu_SvrList_SaveList("cfg/svrlist.dat");
254 
255 						// Click!
256 						PlaySoundSample(sfxGeneral.smpClick);
257 
258 						lv_subitem_t *sub = ((CListview *)cInternet.getWidget(mi_ServerList))->getCurSubitem(1);
259 
260 						// Join
261 						if (sub)
262 							Menu_Net_NETJoinServer(addr,sub->sText);
263 						return;
264 					}
265 				}
266 				break;
267 
268 			// Serverlist
269 			case mi_ServerList:
270 
271                 // Double click
272 				if(ev->iEventMsg == LV_DOUBLECLK) {
273 
274 					/*
275 					  Now.... Should a double click refresh the server (like tribes)?
276 					  Or should it join the server like other games???
277 					*/
278 
279 					// Just join for the moment
280 					addr = "";
281 					int result = cInternet.SendMessage(mi_ServerList, LVS_GETCURSINDEX, &addr, 0);
282 					lv_subitem_t *sub = ((CListview *)cInternet.getWidget(mi_ServerList))->getCurSubitem(1);
283 					if(result != -1 && addr != "" && sub) {
284                         // Save the list
285                         Menu_SvrList_SaveList("cfg/svrlist.dat");
286 
287 						Menu_Net_NETJoinServer(addr,sub->sText);
288 						return;
289 					}
290 				}
291 
292                 // Right click
293                 if( ev->iEventMsg == LV_RIGHTCLK ) {
294                     addr = "";
295 					int result = cInternet.SendMessage(mi_ServerList, LVS_GETCURSINDEX, &addr, 0);
296 					if(result && addr != "") {
297                         // Display a menu
298                         szNetCurServer = addr;
299                         mouse_t *m = GetMouse();
300 
301                         cInternet.Add( new CMenu(m->X, m->Y), mi_PopupMenu, 0,0, 640,480 );
302                         cInternet.SendMessage( mi_PopupMenu, MNS_ADDITEM, "Delete server",				0 );
303                         cInternet.SendMessage( mi_PopupMenu, MNS_ADDITEM, "Refresh server",				1 );
304                         cInternet.SendMessage( mi_PopupMenu, MNS_ADDITEM, "Join server",				2 );
305 						cInternet.SendMessage( mi_PopupMenu, MNS_ADDITEM, "Add to favourites",			3 );
306 						cInternet.SendMessage( mi_PopupMenu, MNS_ADDITEM, "Send \"I want to join message\"",4 );
307 						cInternet.SendMessage( mi_PopupMenu, MNS_ADDITEM, "Copy IP to clipboard",		5 );
308                         cInternet.SendMessage( mi_PopupMenu, MNS_ADDITEM, "Server details",				6 );
309                     }
310                 }
311 
312 
313 				// Enter key
314 				if( ev->iEventMsg == LV_ENTER )  {
315 					// Join
316 					addr = "";
317 					int result = cInternet.SendMessage(mi_ServerList, LVS_GETCURSINDEX, &addr, 0);
318 					lv_subitem_t *sub = ((CListview *)cInternet.getWidget(mi_ServerList))->getCurSubitem(1);
319 					if(result != -1 && addr != "" && sub) {
320                         // Save the list
321                         Menu_SvrList_SaveList("cfg/svrlist.dat");
322 
323 						Menu_Net_NETJoinServer(addr,sub->sText);
324 						return;
325 					}
326 				}
327 
328 				// Delete
329 				if( ev->iEventMsg == LV_DELETE )  {
330 					addr = "";
331 					int result = cInternet.SendMessage(mi_ServerList, LVS_GETCURSINDEX, &addr, 0);
332 					if(result && addr != "") {
333 						Menu_SvrList_RemoveServer(addr);
334 						// Re-Fill the server list
335 						Menu_SvrList_FillList( (CListview *)cInternet.getWidget( mi_ServerList ) );
336 					}
337 				}
338 				break;
339 
340             // Popup menu
341             case mi_PopupMenu:
342                 switch( ev->iEventMsg ) {
343                     // Delete the server
344                     case MNU_USER+0:
345                         Menu_SvrList_RemoveServer(szNetCurServer);
346                         break;
347 
348                     // Refresh the server
349                     case MNU_USER+1:
350                         {
351                             server_t *sv = Menu_SvrList_FindServerStr(szNetCurServer);
352                             if(sv)
353                                 Menu_SvrList_RefreshServer(sv);
354                         }
355                         break;
356 
357                     // Join a server
358                     case MNU_USER+2:  {
359                         // Save the list
360                         Menu_SvrList_SaveList("cfg/svrlist.dat");
361 						lv_subitem_t *sub = ((CListview *)cInternet.getWidget(mi_ServerList))->getCurSubitem(1);
362 						if (sub)
363 							Menu_Net_NETJoinServer(szNetCurServer,sub->sText);
364 						}
365                         return;
366 
367                     // Add server to favourites
368                     case MNU_USER+3:
369 						{
370 							server_t *sv = Menu_SvrList_FindServerStr(szNetCurServer);
371 							if (sv)
372 								Menu_SvrList_AddFavourite(sv->szName,sv->szAddress);
373 						}
374                         break;
375 
376 					// Send a "wants to join" message
377                     case MNU_USER+4:
378 						{
379 							server_t *sv = Menu_SvrList_FindServerStr(szNetCurServer);
380 							std::string Nick;
381 							cInternet.SendMessage(mi_PlayerSelection, CBS_GETCURNAME, &Nick, 0);
382 							if (sv)
383 								Menu_SvrList_WantsJoin(Nick, sv);
384 						}
385                         break;
386 
387 					// Copy the IP to clipboard
388 					case MNU_USER+5:
389 						{
390 							copy_to_clipboard(szNetCurServer);
391 						}
392 						break;
393 
394                     // Show server details
395                     case MNU_USER+6:
396 						cInternet.removeWidget(mi_PopupMenu);
397                         Menu_Net_NETShowServer(szNetCurServer);
398                         break;
399                 }
400 
401                 // Re-Fill the server list
402                 Menu_SvrList_FillList( (CListview *)cInternet.getWidget( mi_ServerList ) );
403 
404                 // Remove the menu widget
405                 cInternet.SendMessage( mi_PopupMenu, MNM_REDRAWBUFFER, (DWORD)0, 0);
406                 cInternet.removeWidget(mi_PopupMenu);
407                 break;
408 
409 			// Update server list
410 			case mi_UpdateList:
411 				if(ev->iEventMsg == BTN_CLICKED) {
412 					// Click!
413 					PlaySoundSample(sfxGeneral.smpClick);
414 
415 					Menu_Net_NETUpdateList();
416 				}
417 				break;
418 		}
419 
420 	}
421 
422 	// F5 updates the list
423 	if (WasKeyboardEventHappening(SDLK_F5))
424 		Menu_Net_NETUpdateList();
425 
426 	// Draw the mouse
427 	DrawCursor(VideoPostProcessor::videoSurface());
428 
429 }
430 
431 
432 
433 ///////////////////
434 // Join a server
Menu_Net_NETJoinServer(const std::string & sAddress,const std::string & sName)435 void Menu_Net_NETJoinServer(const std::string& sAddress, const std::string& sName)
436 {
437 	// Fill in the game structure
438 	CCombobox* combo = (CCombobox *) cInternet.getWidget(mi_PlayerSelection);
439 	const cb_item_t* item = combo->getSelectedItem();
440 	if(!item) {
441 		errors << "no player selected" << endl;
442 		return;
443 	}
444 
445 	tLXOptions->sLastSelectedPlayer = item->sIndex;
446 
447 	if(!JoinServer(sAddress, sName, item->sIndex))
448 		return;
449 
450 	// Shutdown
451 	cInternet.Shutdown();
452 
453 	iNetMode = net_join;
454 	tMenu->iReturnTo = net_internet;
455 
456 	// Connect to the server
457 	Menu_Net_JoinConnectionInitialize(sAddress);
458 }
459 
460 
461 ///////////////////
462 // Show an 'add server' box to enter in an address
463 enum  {
464 	na_Cancel=0,
465 	na_Add,
466 	na_Address
467 };
468 
Menu_Net_NETAddServer()469 void Menu_Net_NETAddServer()
470 {
471 	CGuiLayout	cAddSvr;
472 	gui_event_t *ev = NULL;
473 	bool		addServerMsg = true;
474 
475 
476 	// Create the background
477 	cInternet.Draw( tMenu->bmpBuffer.get() );
478 	Menu_DrawBox(tMenu->bmpBuffer.get(), 200, 220, 440, 340);
479 	//DrawImageAdv(tMenu->bmpBuffer, tMenu->bmpMainBack, 202,222, 202,222, 237,117);
480     DrawRectFill(tMenu->bmpBuffer.get(), 202,222,439,339,tLX->clDialogBackground);
481 
482 	Menu_RedrawMouse(true);
483 
484 
485 	cAddSvr.Initialize();
486 	cAddSvr.Add( new CButton(BUT_ADD, tMenu->bmpButtons),	na_Add, 220, 320, 40,15);
487 	cAddSvr.Add( new CButton(BUT_CANCEL, tMenu->bmpButtons),na_Cancel, 350, 320, 70,15);
488 	cAddSvr.Add( new CLabel("Add a server", tLX->clNormalLabel),		-1,275, 225, 0, 0);
489 	cAddSvr.Add( new CLabel("Address", tLX->clNormalLabel),				-1,215, 267, 0, 0);
490 	cAddSvr.Add( new CTextbox(),							na_Address, 280, 265, 140, tLX->cFont.GetHeight());
491 
492 	ProcessEvents();
493 	while(!WasKeyboardEventHappening(SDLK_ESCAPE,false) && addServerMsg && tMenu->bMenuRunning) {
494 		Menu_RedrawMouse(true);
495 		DrawImageAdv(VideoPostProcessor::videoSurface(),tMenu->bmpBuffer, 200,220, 200,220, 240, 240);
496 
497 		ProcessEvents();
498 
499 		// Process the server list
500 		if( Menu_SvrList_Process() ) {
501 			// Add the servers to the listview
502 			Menu_SvrList_FillList( (CListview *)cInternet.getWidget( mi_ServerList ) );
503 		}
504 
505 		cAddSvr.Draw( VideoPostProcessor::videoSurface() );
506 		ev = cAddSvr.Process();
507 
508 		// Process any events
509 		if(ev) {
510 
511 			switch(ev->iControlID) {
512 
513 				// Add
514 				case na_Add:
515 					if(ev->iEventMsg == BTN_CLICKED) {
516 
517 						std::string addr;
518 						cAddSvr.SendMessage(na_Address, TXS_GETTEXT, &addr, 0);
519 
520 						Menu_SvrList_AddServer(addr, true);
521 						Menu_SvrList_FillList( (CListview *)cInternet.getWidget( mi_ServerList ) );
522 
523 						// Click!
524 						PlaySoundSample(sfxGeneral.smpClick);
525 
526 						addServerMsg = false;
527 					}
528 					break;
529 
530 				// Cancel
531 				case na_Cancel:
532 					if(ev->iEventMsg == BTN_CLICKED) {
533 						// Click!
534 						PlaySoundSample(sfxGeneral.smpClick);
535 
536 						addServerMsg = false;
537 					}
538 					break;
539 			}
540 		}
541 
542 
543 		DrawCursor(VideoPostProcessor::videoSurface());
544 		doVideoFrameInMainThread();
545 		CapFPS();
546 	}
547 
548 
549 	cAddSvr.Shutdown();
550 
551 	// Re-draw the background
552 	DrawImage(tMenu->bmpBuffer.get(),tMenu->bmpMainBack_common,0,0);
553 	Menu_DrawSubTitle(tMenu->bmpBuffer.get(),SUB_NETWORK);
554 	if (tMenu->tFrontendInfo.bPageBoxes)
555 		Menu_DrawBox(tMenu->bmpBuffer.get(), 15,130, 625, 465);
556 	Menu_RedrawMouse(true);
557 }
558 
559 
560 
561 ///////////////////
562 // Update the server list
Menu_Net_NETUpdateList()563 void Menu_Net_NETUpdateList()
564 {
565 	CGuiLayout	cListUpdate;
566 	gui_event_t *ev = NULL;
567 	bool		updateList = true;
568 	int			http_result = 0;
569 	std::string szLine;
570 
571     // Clear the server list
572     Menu_SvrList_ClearAuto();
573 
574 	// UDP list
575 	Menu_SvrList_UpdateUDPList();
576 
577     //
578     // Get the number of master servers for a progress bar
579     //
580     int SvrCount = 0;
581     int CurServer = 0;
582     bool SentRequest = false;
583     FILE *fp = OpenGameFile("cfg/masterservers.txt","rt");
584 	if( !fp )  {
585 		errors << "Cannot update list because there is no masterservers.txt file available\n" << endl;
586         return;
587 	}
588 
589 	// TODO: i don't understand it, why are we doing it so complicated here, why not just save it in a list?
590     while( !feof(fp) ) {
591         szLine = ReadUntil(fp);
592 		TrimSpaces(szLine);
593 
594         if( szLine.length() > 0 && szLine[0] != '#' )
595             SvrCount++;
596     }
597 
598     // Back to the start
599     fseek(fp, 0, SEEK_SET);
600 
601 	// Create the background
602 	cInternet.Draw( tMenu->bmpBuffer.get() );
603 	Menu_DrawBox(tMenu->bmpBuffer.get(), 200, 220, 440, 340);
604 	//DrawImageAdv(tMenu->bmpBuffer, tMenu->bmpMainBack, 202,222, 202,222, 237,117);
605     DrawRectFill(tMenu->bmpBuffer.get(), 202, 222, 439, 339, tLX->clDialogBackground);
606     Menu_DrawBox(tMenu->bmpBuffer.get(), 220, 280, 420, 300);
607 
608 	Menu_RedrawMouse(true);
609 
610 
611 	cListUpdate.Initialize();
612 	cListUpdate.Add( new CButton(BUT_CANCEL, tMenu->bmpButtons),0, 285, 320, 70,15);
613 	cListUpdate.Add( new CLabel("Getting server list", tLX->clNormalLabel),	-1,260, 227, 0, 0);
614 
615 
616 	CHttp http;
617 
618 	while(!WasKeyboardEventHappening(SDLK_ESCAPE,false) && updateList && tMenu->bMenuRunning) {
619 		tLX->currentTime = GetTime();
620 
621 		Menu_RedrawMouse(true);
622 		ProcessEvents();
623 		DrawImageAdv(VideoPostProcessor::videoSurface(),tMenu->bmpBuffer, 200,220, 200,220, 240, 240);
624 
625         if( SvrCount > 0 ) {
626             DrawRectFill(VideoPostProcessor::videoSurface(), 222,282, (int) (222+((float)CurServer/(float)SvrCount)*200.0f), 299, tLX->clProgress);
627             tLX->cOutlineFont.DrawCentre(VideoPostProcessor::videoSurface(), 320,283,tLX->clWhite, itoa(CurServer) + "/" + itoa(SvrCount));
628         }
629 
630         // Do the HTTP requests of the master servers
631         if( !SentRequest ) {
632 
633             // Have we gone through all the servers?
634             if( CurServer >= SvrCount )
635                 break;
636 
637             // Get the next server in the list
638             while( !feof(fp) ) {
639 				szLine = ReadUntil(fp);
640 				TrimSpaces(szLine);
641 
642                 if( szLine.length() > 0 && szLine[0] != '#' ) {
643 
644                     // Send the request
645 					//notes << "Getting serverlist from " + szLine + "..." << endl;
646 					http.RequestData(szLine + LX_SVRLIST, tLXOptions->sHttpProxy);
647 					SentRequest = true;
648 
649                     break;
650                 }
651             }
652         } else { // Process the http request
653             http_result = http.ProcessRequest();
654 
655             // Parse the list if the request was successful
656             if (http_result == HTTP_PROC_FINISHED) {
657 		        Menu_Net_NETParseList(http);
658 
659 				// Other master servers could have more server so we process them anyway
660 				SentRequest = false;
661 				CurServer++;
662 			} else if (http_result == HTTP_PROC_ERROR)  {
663 				if (http.GetError().iError != HTTP_NO_ERROR)
664             		errors << "HTTP ERROR: " << http.GetError().sErrorMsg << endl;
665 				// Jump to next server
666 				SentRequest = false;
667 				CurServer++;
668 				http.CancelProcessing();
669 			}
670         }
671 
672 		cListUpdate.Draw( VideoPostProcessor::videoSurface() );
673 		ev = cListUpdate.Process();
674 
675 		// Process any events
676 		if(ev) {
677 			if (ev->iControlID == 0 && ev->iEventMsg == BTN_CLICKED)  {  // Cancel
678 				// Click!
679 				PlaySoundSample(sfxGeneral.smpClick);
680 
681 				http_result = 0;
682 				updateList = false;
683 				break;
684 			}
685 		}
686 
687 
688 		DrawCursor(VideoPostProcessor::videoSurface());
689 		doVideoFrameInMainThread();
690 		CapFPS();
691 	}
692 
693 	cListUpdate.Shutdown();
694 	fclose(fp);
695 
696 	Menu_SvrList_FillList( (CListview *)cInternet.getWidget( mi_ServerList ) );
697 
698 
699 	// Re-draw the background
700 	DrawImage(tMenu->bmpBuffer.get(),tMenu->bmpMainBack_common,0,0);
701 	if (tMenu->tFrontendInfo.bPageBoxes)
702 		Menu_DrawBox(tMenu->bmpBuffer.get(), 15,130, 625, 465);
703 	Menu_DrawSubTitle(tMenu->bmpBuffer.get(),SUB_NETWORK);
704 	Menu_RedrawMouse(true);
705 }
706 
707 
708 ///////////////////
709 // Parse the downloaded server list
Menu_Net_NETParseList(CHttp & http)710 void Menu_Net_NETParseList(CHttp &http)
711 {
712 	const std::string& content = http.GetData();
713 
714 	std::string addr, ptr;
715 
716 	std::string::const_iterator it = content.begin();
717 	size_t i = 0;
718 	size_t startpos = 0;
719 	for(; it != content.end(); it++, i++) {
720 		if(*it != '\n') continue;
721 		std::vector<std::string> tokens = explode(content.substr(startpos, i-startpos), ",");
722 		startpos = i+1;
723 
724 		// we need at least 2 items
725 		if(tokens.size() < 2) continue;
726 
727 		addr = tokens[0];
728 		ptr = tokens[1];
729 
730 		TrimSpaces(addr);
731 		TrimSpaces(ptr);
732 
733 		// If the address, or port does NOT have quotes around it, the line must be mangled and cannot be used
734 		if(addr.size() <= 2 || ptr.size() <= 2) continue;
735 		if(addr[0] != '\"' || ptr[0] != '\"') continue;
736 		if(addr[addr.size()-1] != '\"' || ptr[ptr.size()-1] != '\"') continue;
737 
738 		StripQuotes(addr);
739 		StripQuotes(ptr);
740 
741 		// Create the server address
742 		Menu_SvrList_AddServer(addr + ":" + ptr, false);
743 	}
744 
745 	// Update the GUI
746 	Timer("Menu_Net_NETParseList ping waiter", null, NULL, PingWait, true).startHeadless();
747 }
748 
749 enum  {
750 	nd_Ok=0,
751 	nd_Refresh,
752 	nd_Join
753 };
754 
755 ///////////////////
756 // Show a server's details
Menu_Net_NETShowServer(const std::string & szAddress)757 void Menu_Net_NETShowServer(const std::string& szAddress)
758 {
759     CGuiLayout  cDetails;
760 
761     // Create the buffer
762     DrawImage(tMenu->bmpBuffer.get(),tMenu->bmpMainBack_common,0,0);
763     Menu_DrawBox(tMenu->bmpBuffer.get(), 15,130, 625, 465);
764 	Menu_DrawSubTitle(tMenu->bmpBuffer.get(),SUB_NETWORK);
765 	cInternet.Draw(tMenu->bmpBuffer.get());
766 
767 	Menu_RedrawMouse(true);
768 
769 	int center = VideoPostProcessor::videoSurface()->w/2;
770 	int y = VideoPostProcessor::videoSurface()->h/2 - INFO_H/2;
771 
772     cDetails.Initialize();
773 	cDetails.Add( new CButton(BUT_REFRESH, tMenu->bmpButtons),  nd_Refresh,	center - 105, y+INFO_H-20, 85,15);
774     cDetails.Add( new CButton(BUT_JOIN, tMenu->bmpButtons),	    nd_Join,    center, y+INFO_H-20, 40,45);
775 	cDetails.Add( new CButton(BUT_OK, tMenu->bmpButtons),	    nd_Ok,      center + 60, y+INFO_H-20, 40,15);
776 	((CButton *)cDetails.getWidget(nd_Refresh))->setRedrawMenu(false);
777 	((CButton *)cDetails.getWidget(nd_Ok))->setRedrawMenu(false);
778 	((CButton *)cDetails.getWidget(nd_Join))->setRedrawMenu(false);
779 
780 	bGotDetails = false;
781 	bOldLxBug = false;
782 	nTries = 0;
783 	fStart = AbsTime();
784 
785     while(!WasKeyboardEventHappening(SDLK_ESCAPE,false) && tMenu->bMenuRunning) {
786 		tLX->currentTime = GetTime();
787 
788 		Menu_RedrawMouse(true);
789 		ProcessEvents();
790 		//DrawImageAdv(VideoPostProcessor::videoSurface(),tMenu->bmpBuffer, 200,220, 200,220, 240, 240);
791 
792 		Menu_SvrList_DrawInfo(szAddress, INFO_W, INFO_H);
793 
794         cDetails.Draw(VideoPostProcessor::videoSurface());
795         gui_event_t *ev = NULL;
796 
797 		ev = cDetails.Process();
798         if(ev) {
799 
800 			// Ok
801             if(ev->iControlID == nd_Ok && ev->iEventMsg == BTN_CLICKED) {
802                 break;
803 			// Refresh
804             } else if (ev->iControlID == nd_Refresh && ev->iEventMsg == BTN_CLICKED)  {
805 				fStart = AbsTime();
806 				bGotDetails = false;
807 				bOldLxBug = false;
808 				nTries = 0;
809 			} else if (ev->iControlID == nd_Join && ev->iEventMsg == BTN_CLICKED)  {
810                 // Save the list
811                 Menu_SvrList_SaveList("cfg/svrlist.dat");
812 
813 				lv_subitem_t *sub = ((CListview *)cInternet.getWidget(mi_ServerList))->getCurSubitem(1);
814 
815 				// Join
816 				if (sub)
817 					Menu_Net_NETJoinServer(szAddress, sub->sText);
818 
819 				break;
820 			}
821         }
822 
823         DrawCursor(VideoPostProcessor::videoSurface());
824 		doVideoFrameInMainThread();
825 		CapFPS();
826     }
827 
828 	cDetails.Shutdown();
829 
830 
831     // Redraw the background
832 	DrawImage(tMenu->bmpBuffer.get(),tMenu->bmpMainBack_common,0,0);
833 	if (tMenu->tFrontendInfo.bPageBoxes)
834 		Menu_DrawBox(tMenu->bmpBuffer.get(), 15,130, 625, 465);
835 	Menu_DrawSubTitle(tMenu->bmpBuffer.get(),SUB_NETWORK);
836 	Menu_RedrawMouse(true);
837 }
838 
839 }; // namespace DeprecatedGUI
840