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