1 /*
2
3 *************************************************************************
4
5 ArmageTron -- Just another Tron Lightcycle Game in 3D.
6 Copyright (C) 2000 Manuel Moos (manuel@moosnet.de)
7
8 **************************************************************************
9
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 ***************************************************************************
25
26 */
27
28 #include "gServerBrowser.h"
29 #include "gGame.h"
30 #include "gLogo.h"
31 #include "gServerFavorites.h"
32 #include "gFriends.h"
33
34 #include "nServerInfo.h"
35 #include "nNetwork.h"
36
37 #include "rSysdep.h"
38 #include "rScreen.h"
39 #include "rConsole.h"
40 #include "rRender.h"
41
42 #include "uMenu.h"
43 #include "uInputQueue.h"
44
45 #include "tMemManager.h"
46 #include "tSysTime.h"
47 #include "tToDo.h"
48
49 #include "tDirectories.h"
50 #include "tConfiguration.h"
51
52 int gServerBrowser::lowPort = 4534;
53
54 int gServerBrowser::highPort = 4540;
55 static bool continuePoll = false;
56 static int sg_simultaneous = 20;
57 static tSettingItem< int > sg_simultaneousConf( "BROWSER_QUERIES_SIMULTANEOUS", sg_simultaneous );
58
59 static tOutput *sg_StartHelpText = NULL;
60
61 nServerInfo::QueryType sg_queryType = nServerInfo::QUERY_OPTOUT;
62 tCONFIG_ENUM( nServerInfo::QueryType );
63 static tSettingItem< nServerInfo::QueryType > sg_query_type( "BROWSER_QUERY_FILTER", sg_queryType );
64
65 class gServerMenuItem;
66
67
68 class gServerInfo: public nServerInfo
69 {
70 public:
71 gServerMenuItem *menuItem;
72 bool show; //for server browser hiding
73
gServerInfo()74 gServerInfo():menuItem(NULL), show(true)
75 {
76 }
77
78 virtual ~gServerInfo();
79
80 // during browsing, the whole server list consists of gServerInfos
GetFirstServer()81 static gServerInfo * GetFirstServer()
82 {
83 return dynamic_cast< gServerInfo * >( nServerInfo::GetFirstServer() );
84 }
85
Next()86 gServerInfo * Next()
87 {
88 return dynamic_cast< gServerInfo * >( nServerInfo::Next() );
89 }
90 };
91
CreateGServer()92 nServerInfo* CreateGServer()
93 {
94 nServerInfo *ret = tNEW(gServerInfo);
95
96 //if (!continuePoll)
97 //{
98 // nServerInfo::StartQueryAll( sg_queryType );
99 // continuePoll = true;
100 // }
101
102 return ret;
103 }
104
105
106 class gServerMenu: public uMenu
107 {
108 int sortKey_;
109
110 public:
111 virtual void OnRender();
112
113 void Update(); // sort the server view by score
114 gServerMenu(const char *title);
115 ~gServerMenu();
116
117 virtual void HandleEvent( SDL_Event event );
118
119 void Render(REAL y,
120 const tString &servername, const tOutput &score,
121 const tOutput &users , const tOutput &ping);
122
123 void Render(REAL y,
124 const tString &servername, const tString &score,
125 const tString &users , const tString &ping);
126 };
127
128
129 class gBrowserMenuItem: public uMenuItem
130 {
131 protected:
gBrowserMenuItem(uMenu * M,const tOutput & help)132 gBrowserMenuItem(uMenu *M,const tOutput &help): uMenuItem( M, help )
133 {
134 }
135
136 // handles a key press
137 virtual bool Event( SDL_Event& event );
138
139 virtual void RenderBackground();
140 };
141
142 class gServerMenuItem: public gBrowserMenuItem
143 {
144 protected:
145 gServerInfo *server;
146 double lastPing_; //!< the time of the last manual ping
147 bool favorite_; //!< flag indicating whether this is a favorite
148 public:
149 void AddFavorite();
150 void SetServer(nServerInfo *s);
151 gServerInfo *GetServer();
152
153 virtual void Render(REAL x,REAL y,REAL alpha=1, bool selected=0);
154 virtual void RenderBackground();
155
156 virtual void Enter();
157
158 // handles a key press
159 virtual bool Event( SDL_Event& event );
160
161 gServerMenuItem(gServerMenu *men);
162 virtual ~gServerMenuItem();
163 };
164
165 class gServerStartMenuItem: public gBrowserMenuItem
166 {
167 public:
168 virtual void Render(REAL x,REAL y,REAL alpha=1, bool selected=0);
169
170 virtual void Enter();
171
172 gServerStartMenuItem(gServerMenu *men);
173 virtual ~gServerStartMenuItem();
174 };
175
176
177
178
179
180
181 static bool sg_RequestLANcontinuously = false;
182
BrowseMaster()183 void gServerBrowser::BrowseMaster()
184 {
185 BrowseSpecialMaster(0,"");
186 }
187
188 // the currently active master
189 static nServerInfoBase * sg_currentMaster = 0;
CurrentMaster()190 nServerInfoBase * gServerBrowser::CurrentMaster()
191 {
192 return sg_currentMaster;
193 }
194
195
BrowseSpecialMaster(nServerInfoBase * master,char const * prefix)196 void gServerBrowser::BrowseSpecialMaster( nServerInfoBase * master, char const * prefix )
197 {
198 sg_currentMaster = master;
199
200 sg_RequestLANcontinuously = false;
201
202 sn_ServerInfoCreator *cback = nServerInfo::SetCreator(&CreateGServer);
203
204 sr_con.autoDisplayAtNewline=true;
205 sr_con.fullscreen=true;
206
207 #ifndef DEDICATED
208 rSysDep::SwapGL();
209 rSysDep::ClearGL();
210 rSysDep::SwapGL();
211 rSysDep::ClearGL();
212 #endif
213
214 bool to=sr_textOut;
215 sr_textOut=true;
216
217 nServerInfo::DeleteAll();
218 nServerInfo::GetFromMaster( master, prefix );
219 nServerInfo::Save();
220
221 // gLogo::SetBig(true);
222 // gLogo::SetSpinning(false);
223
224 sr_textOut = to;
225
226 tOutput StartHelpTextInternet("$network_master_host_inet_help");
227 sg_StartHelpText = &StartHelpTextInternet;
228 sg_TalkToMaster = true;
229
230 BrowseServers();
231
232 nServerInfo::Save();
233
234 sg_TalkToMaster = false;
235
236 nServerInfo::SetCreator(cback);
237
238 sg_currentMaster = master;
239 }
240
BrowseLAN()241 void gServerBrowser::BrowseLAN()
242 {
243 // TODO: reacivate and see what happens. Done.
244 sg_RequestLANcontinuously = true;
245 // sg_RequestLANcontinuously = false;
246
247 sn_ServerInfoCreator *cback = nServerInfo::SetCreator(&CreateGServer);
248
249 sr_con.autoDisplayAtNewline=true;
250 sr_con.fullscreen=true;
251
252 #ifndef DEDICATED
253 rSysDep::SwapGL();
254 rSysDep::ClearGL();
255 rSysDep::SwapGL();
256 rSysDep::ClearGL();
257 #endif
258
259 bool to=sr_textOut;
260 sr_textOut=true;
261
262 nServerInfo::DeleteAll();
263 nServerInfo::GetFromLAN(lowPort, highPort);
264
265 sr_textOut = to;
266
267 tOutput StartHelpTextLAN("$network_master_host_lan_help");
268 sg_StartHelpText = &StartHelpTextLAN;
269 sg_TalkToMaster = false;
270
271 BrowseServers();
272
273 nServerInfo::SetCreator(cback);
274 }
275
BrowseServers()276 void gServerBrowser::BrowseServers()
277 {
278 //nServerInfo::CalcScoreAll();
279 //nServerInfo::Sort();
280 nServerInfo::StartQueryAll( sg_queryType );
281 continuePoll = true;
282
283 gServerMenu browser("Server Browser");
284
285 gServerStartMenuItem start(&browser);
286
287 /*
288 while (nServerInfo::DoQueryAll(sg_simultaneous));
289 sn_SetNetState(nSTANDALONE);
290 nServerInfo::Sort();
291
292 if (nServerInfo::GetFirstServer())
293 ConnectToServer(nServerInfo::GetFirstServer());
294 */
295 browser.Update();
296
297 // eat excess input the user made while the list was fetched
298 SDL_Event ignore;
299 REAL time;
300 while(su_GetSDLInput(ignore, time)) ;
301
302 browser.Enter();
303
304 nServerInfo::GetFromLANContinuouslyStop();
305
306 // gLogo::SetBig(false);
307 // gLogo::SetSpinning(true);
308 // gLogo::SetDisplayed(true);
309 }
310
311
312
313
314
HandleEvent(SDL_Event event)315 void gServerMenu::HandleEvent( SDL_Event event )
316 {
317 #ifndef DEDICATED
318 switch (event.type)
319 {
320 case SDL_KEYDOWN:
321 switch (event.key.keysym.sym)
322 {
323 case(SDLK_LEFT):
324 sortKey_ = ( sortKey_ + nServerInfo::KEY_MAX-1 ) % nServerInfo::KEY_MAX;
325 Update();
326 return;
327 break;
328 case(SDLK_RIGHT):
329 sortKey_ = ( sortKey_ + 1 ) % nServerInfo::KEY_MAX;
330 Update();
331 return;
332 break;
333 case(SDLK_m):
334 FriendsToggle();
335 Update();
336 return;
337 break;
338 default:
339 break;
340 }
341 }
342 #endif
343
344 uMenu::HandleEvent( event );
345 }
346
OnRender()347 void gServerMenu::OnRender()
348 {
349 uMenu::OnRender();
350
351 // next time the server list is to be resorted
352 static double sg_serverMenuRefreshTimeout=-1E+32f;
353
354 if (sg_serverMenuRefreshTimeout < tSysTimeFloat())
355 {
356 Update();
357 sg_serverMenuRefreshTimeout = tSysTimeFloat()+2.0f;
358 }
359 }
360
Update()361 void gServerMenu::Update()
362 {
363 // get currently selected server
364 gServerMenuItem *item = NULL;
365 if ( selected < items.Len() )
366 {
367 item = dynamic_cast<gServerMenuItem*>(items(selected));
368 }
369 gServerInfo* info = NULL;
370 if ( item )
371 {
372 info = item->GetServer();
373 }
374
375 // keep the cursor position relative to the top, if possible
376 int selectedFromTop = items.Len() - selected;
377
378 ReverseItems();
379
380 nServerInfo::CalcScoreAll();
381 nServerInfo::Sort( nServerInfo::PrimaryKey( sortKey_ ) );
382
383 int mi = 1;
384 gServerInfo *run = gServerInfo::GetFirstServer();
385 bool oneFound = false; //so we can display all if none were found
386 while (run)
387 {
388 //check friend filter
389 if (getFriendsEnabled())
390 {
391 run->show = false;
392 int i;
393 tString userNames = run->UserNames();
394 tString* friends = getFriends();
395 for (i = MAX_FRIENDS-1; i>=0; i--)
396 {
397 if (run->Users() > 0 && friends[i].Len() > 1 && userNames.StrPos(friends[i]) >= 0)
398 {
399 oneFound = true;
400 run->show = true;
401 }
402 }
403 }
404 run = run->Next();
405 }
406
407 run = gServerInfo::GetFirstServer();
408 {
409 while (run)
410 {
411 if (run->show || oneFound == false)
412 {
413 if (mi >= items.Len())
414 tNEW(gServerMenuItem)(this);
415
416 gServerMenuItem *item = dynamic_cast<gServerMenuItem*>(items(mi));
417 item->SetServer(run);
418 mi++;
419 }
420 run = run->Next();
421 }
422 }
423
424 if (items.Len() == 1)
425 selected = 1;
426
427 while(mi < items.Len() && items.Len() > 2)
428 {
429 uMenuItem *it = items(items.Len()-1);
430 delete it;
431 }
432
433 ReverseItems();
434
435 // keep the cursor position relative to the top, if possible ( calling function will handle the clamping )
436 selected = items.Len() - selectedFromTop;
437
438 // set cursor to currently selected server, if possible
439 if ( info && info->menuItem )
440 {
441 selected = info->menuItem->GetID();
442 }
443
444 if (sg_RequestLANcontinuously)
445 {
446 static REAL timeout=-1E+32f;
447
448 if (timeout < tSysTimeFloat())
449 {
450 nServerInfo::GetFromLANContinuously();
451 if (!continuePoll)
452 {
453 nServerInfo::StartQueryAll( sg_queryType );
454 continuePoll = true;
455 }
456 timeout = tSysTimeFloat()+10;
457 }
458 }
459 }
460
gServerMenu(const char * title)461 gServerMenu::gServerMenu(const char *title)
462 : uMenu(title, false)
463 , sortKey_( nServerInfo::KEY_SCORE )
464 {
465 nServerInfo *run = nServerInfo::GetFirstServer();
466 while (run)
467 {
468 gServerMenuItem *item = tNEW(gServerMenuItem)(this);
469 item->SetServer(run);
470 run = run->Next();
471 }
472
473 ReverseItems();
474
475 if (items.Len() <= 0)
476 {
477 selected = 1;
478 tNEW(gServerMenuItem)(this);
479 }
480 else
481 selected = items.Len();
482 }
483
~gServerMenu()484 gServerMenu::~gServerMenu()
485 {
486 for (int i=items.Len()-1; i>=0; i--)
487 delete items(i);
488 }
489
490 #ifndef DEDICATED
491 static REAL text_height=.05;
492 static REAL text_width=.025;
493
494 static REAL shrink = .6f;
495 static REAL displace = .15;
496
Render(REAL y,const tString & servername,const tString & score,const tString & users,const tString & ping)497 void gServerMenu::Render(REAL y,
498 const tString &servername, const tString &score,
499 const tString &users , const tString &ping)
500 {
501 if (sr_glOut)
502 {
503 rTextField c(-.9f, y+text_height*.5, text_width, text_height);
504 c.SetWidth(1000);
505
506 c.SetIndent(5);
507
508
509 //int posDisplacement = 0;
510 tColoredString text;
511 if (tColoredString::RemoveColors(servername).Len() > 1)
512 {
513 text << servername << "0xRESETT";
514 }
515 else
516 text << tOutput("$network_master_unknown");
517
518 if (ping.Len() > 1)
519 {
520 text.SetPos(static_cast<int>(1.35/c.GetCWidth()) - tColoredString::RemoveColors( ping ).Len() - 1, true );
521 text << "0xRESETT";
522 text << " " << ping;
523 }
524 else
525 {
526 text << "0xRESETT";
527 }
528
529 if (users.Len() > 1)
530 {
531 text.SetPos(static_cast<int>(1.6/c.GetCWidth()) - tColoredString::RemoveColors( users ).Len(), false );
532 text << users;
533 }
534
535 if (score.Len() > 1)
536 {
537 text.SetPos(static_cast<int>(1.8/c.GetCWidth()) - tColoredString::RemoveColors( score ).Len(), false );
538 text << score;
539 }
540
541 c << text;
542 }
543 }
544
Render(REAL y,const tString & servername,const tOutput & score,const tOutput & users,const tOutput & ping)545 void gServerMenu::Render(REAL y,
546 const tString &servername, const tOutput &score,
547 const tOutput &users , const tOutput &ping)
548 {
549 tColoredString highlight, normal;
550 highlight << tColoredString::ColorString( 1,.7,.7 );
551 normal << tColoredString::ColorString( .7,.3,.3 );
552
553 tString sn, s, u, p;
554
555 sn << normal;
556 s << normal;
557 u << normal;
558 p << normal;
559
560 switch ( sortKey_ )
561 {
562 case nServerInfo::KEY_NAME:
563 sn = highlight;
564 break;
565 case nServerInfo::KEY_PING:
566 p = highlight;
567 break;
568 case nServerInfo::KEY_USERS:
569 u = highlight;
570 break;
571 case nServerInfo::KEY_SCORE:
572 s = highlight;
573 break;
574 case nServerInfo::KEY_MAX:
575 break;
576 }
577
578 sn << servername;// tColoredString::RemoveColors( servername );
579 s << score;
580 u << users;
581 p << ping;
582
583 Render(y, sn, s, u, p);
584 }
585
586 #endif /* DEDICATED */
587 static bool sg_filterServernameColorStrings = true;
588 static tSettingItem< bool > removeServerNameColors("FILTER_COLOR_SERVER_NAMES", sg_filterServernameColorStrings);
589 static bool sg_filterServernameDarkColorStrings = true;
590 static tSettingItem< bool > removeServerNameDarkColors("FILTER_DARK_COLOR_SERVER_NAMES", sg_filterServernameDarkColorStrings);
591
Render(REAL x,REAL y,REAL alpha,bool selected)592 void gServerMenuItem::Render(REAL x,REAL y,REAL alpha, bool selected)
593 {
594 #ifndef DEDICATED
595 // REAL time=tSysTimeFloat()*10;
596
597 SetColor( selected, alpha );
598
599 gServerMenu *serverMenu = static_cast<gServerMenu*>(menu);
600
601 if (server)
602 {
603 tColoredString name;
604 tString score;
605 tString users;
606 tString ping;
607
608 int p = static_cast<int>(server->Ping()*1000);
609 if (p < 0)
610 p = 0;
611 if (p > 10000)
612 p = 10000;
613
614 int s = static_cast<int>(server->Score());
615 if (server->Score() > 10000)
616 s = 10000;
617 if (server->Score() < -10000)
618 s = -10000;
619
620 if (server->Polling())
621 {
622 score << tOutput("$network_master_polling");
623 }
624 else if (!server->Reachable())
625 {
626 score << tOutput("$network_master_unreachable");
627 }
628 else if ( nServerInfo::Compat_Ok != server->Compatibility() )
629 {
630 switch( server->Compatibility() )
631 {
632 case nServerInfo::Compat_Upgrade:
633 score << tOutput( "$network_master_upgrage" );
634 break;
635 case nServerInfo::Compat_Downgrade:
636 score << tOutput( "$network_master_downgrage" );
637 break;
638 default:
639 score << tOutput( "$network_master_incompatible" );
640 break;
641 }
642 }
643 else if ( server->Users() >= server->MaxUsers() )
644 {
645 score << tOutput( "$network_master_full" );
646 score << " (" << server->Users() << "/" << server->MaxUsers() << ")";
647 }
648 else
649 {
650 if ( favorite_ )
651 {
652 score << "B ";
653 }
654
655 score << s;
656 users << server->Users() << "/" << server->MaxUsers();
657 ping << p;
658 }
659
660 if ( sg_filterServernameColorStrings )
661 name << tColoredString::RemoveColors( server->GetName(), false );
662 else if ( sg_filterServernameDarkColorStrings )
663 name << tColoredString::RemoveColors( server->GetName(), true );
664 else
665 {
666 name << server->GetName();
667 }
668
669 serverMenu->Render(y*shrink + displace,
670 name,
671 score, users, ping);
672 }
673 else
674 {
675 tOutput o("$network_master_noserver");
676 tString s;
677 s << o;
678 serverMenu->Render(y*shrink + displace,
679 s,
680 tString(""), tString(""), tString(""));
681
682 }
683 #endif
684 }
685
686
RenderBackground()687 void gServerMenuItem::RenderBackground()
688 {
689 #ifndef DEDICATED
690 gBrowserMenuItem::RenderBackground();
691
692 if ( server )
693 {
694 rTextField::SetDefaultColor( tColor(1,1,1) );
695
696 rTextField players( -.9, -.3, text_width, text_height );
697 players << tOutput( "$network_master_players" );
698 if ( server->UserNamesOneLine().Len() > 2 )
699 players << server->UserNamesOneLine();
700 else
701 players << tOutput( "$network_master_players_empty" );
702 players << "\n" << tColoredString::ColorString(1,1,1);
703 tColoredString uri;
704 uri << server->Url() << tColoredString::ColorString(1,1,1);
705 players << tOutput( "$network_master_serverinfo", server->Release(), uri, server->Options() );
706 }
707 #endif
708 }
709
710 #ifndef DEDICATED
Refresh()711 static void Refresh()
712 {
713 continuePoll = true;
714 nServerInfo::StartQueryAll( sg_queryType );
715 }
716 #endif
717
Event(SDL_Event & event)718 bool gBrowserMenuItem::Event( SDL_Event& event )
719 {
720 #ifndef DEDICATED
721 switch (event.type)
722 {
723 case SDL_KEYDOWN:
724 switch (event.key.keysym.sym)
725 {
726 case SDLK_r:
727 {
728 static double lastRefresh = - 100; //!< the time of the last manual refresh
729 if ( tSysTimeFloat() - lastRefresh > 2.0 )
730 {
731 lastRefresh = tSysTimeFloat();
732 // trigger refresh
733 st_ToDo( Refresh );
734 return true;
735 }
736 }
737 break;
738 default:
739 break;
740 }
741 }
742 #endif
743
744 return uMenuItem::Event( event );
745 }
746
747
Event(SDL_Event & event)748 bool gServerMenuItem::Event( SDL_Event& event )
749 {
750 #ifndef DEDICATED
751 switch (event.type)
752 {
753 case SDL_KEYDOWN:
754 switch (event.key.keysym.sym)
755 {
756 case SDLK_p:
757 continuePoll = true;
758 if ( server && tSysTimeFloat() - lastPing_ > .5f )
759 {
760 lastPing_ = tSysTimeFloat();
761
762 server->SetQueryType( nServerInfo::QUERY_ALL );
763 server->QueryServer();
764 server->ClearInfoFlags();
765 }
766 return true;
767 break;
768 default:
769 break;
770 }
771 switch (event.key.keysym.unicode)
772 {
773 case '+':
774 if ( server )
775 {
776 server->SetScoreBias( server->GetScoreBias() + 10 );
777 server->CalcScore();
778 }
779 (static_cast<gServerMenu*>(menu))->Update();
780
781 return true;
782 break;
783 case '-':
784 if ( server )
785 {
786 server->SetScoreBias( server->GetScoreBias() - 10 );
787 server->CalcScore();
788 }
789 (static_cast<gServerMenu*>(menu))->Update();
790
791 return true;
792 break;
793 case 'b':
794 if ( server && !favorite_ )
795 {
796 favorite_ = gServerFavorites::AddFavorite( server );
797 }
798 return true;
799 break;
800 default:
801 break;
802 }
803 }
804 #endif
805
806 return gBrowserMenuItem::Event( event );
807 }
808
RenderBackground()809 void gBrowserMenuItem::RenderBackground()
810 {
811 sn_Receive();
812 sn_SendPlanned();
813
814 menu->GenericBackground();
815 if (continuePoll)
816 {
817 continuePoll = nServerInfo::DoQueryAll(sg_simultaneous);
818 sn_Receive();
819 sn_SendPlanned();
820 }
821
822 #ifndef DEDICATED
823 rTextField::SetDefaultColor( tColor(.8,.3,.3,1) );
824
825 tString sn2 = tString(tOutput("$network_master_servername"));
826 if (getFriendsEnabled()) //display that friends filter is on
827 sn2 << " - " << tOutput("$friends_enable");
828
829 static_cast<gServerMenu*>(menu)->Render(.62,
830 sn2,
831 tOutput("$network_master_score"),
832 tOutput("$network_master_users"),
833 tOutput("$network_master_ping"));
834 #endif
835 }
836
Enter()837 void gServerMenuItem::Enter()
838 {
839 nServerInfo::GetFromLANContinuouslyStop();
840
841 menu->Exit();
842
843 // gLogo::SetBig(false);
844 // gLogo::SetSpinning(true);
845 // gLogo::SetDisplayed(false);
846
847 if (server)
848 ConnectToServer(server);
849 }
850
851
SetServer(nServerInfo * s)852 void gServerMenuItem::SetServer(nServerInfo *s)
853 {
854 if (s == server)
855 return;
856
857 if (server)
858 server->menuItem = NULL;
859
860 server = dynamic_cast<gServerInfo*>(s);
861
862 if (server)
863 {
864 if (server->menuItem)
865 server->menuItem->SetServer(NULL);
866
867 server->menuItem = this;
868 }
869
870 favorite_ = gServerFavorites::IsFavorite( server );
871 }
872
GetServer()873 gServerInfo *gServerMenuItem::GetServer()
874 {
875 return server;
876 }
877
878 static char const * sg_HelpText = "$network_master_browserhelp";
879
gServerMenuItem(gServerMenu * men)880 gServerMenuItem::gServerMenuItem(gServerMenu *men)
881 :gBrowserMenuItem(men, sg_HelpText), server(NULL), lastPing_(-100), favorite_(false)
882 {}
883
~gServerMenuItem()884 gServerMenuItem::~gServerMenuItem()
885 {
886 SetServer(NULL);
887
888 // make sure the last entry in the array (the first menuitem)
889 // stays the same
890 uMenuItem* last = menu->Item(menu->NumItems()-1);
891 menu->RemoveItem(last);
892 menu->RemoveItem(this);
893 menu->AddItem(last);
894 }
895
896
~gServerInfo()897 gServerInfo::~gServerInfo()
898 {
899 if (menuItem)
900 delete menuItem;
901 }
902
903
Render(REAL x,REAL y,REAL alpha,bool selected)904 void gServerStartMenuItem::Render(REAL x,REAL y,REAL alpha, bool selected)
905 {
906 #ifndef DEDICATED
907 // REAL time=tSysTimeFloat()*10;
908
909 SetColor( selected, alpha );
910
911 tString s;
912 s << tOutput("$network_master_start");
913 static_cast<gServerMenu*>(menu)->Render(y*shrink + displace,
914 s,
915 tString(), tString(), tString());
916 #endif
917 }
918
Enter()919 void gServerStartMenuItem::Enter()
920 {
921 nServerInfo::GetFromLANContinuouslyStop();
922
923 menu->Exit();
924
925 // gLogo::SetBig(false);
926 // gLogo::SetSpinning(true);
927 // gLogo::SetDisplayed(false);
928
929 sg_HostGameMenu();
930 }
931
932
933
gServerStartMenuItem(gServerMenu * men)934 gServerStartMenuItem::gServerStartMenuItem(gServerMenu *men)
935 :gBrowserMenuItem(men, *sg_StartHelpText)
936 {}
937
~gServerStartMenuItem()938 gServerStartMenuItem::~gServerStartMenuItem()
939 {
940 }
941
942
943