1 // ==============================================================
2 //	This file is part of Glest (www.glest.org)
3 //
4 //	Copyright (C) 2010-  by Titus Tscharntke
5 //
6 //	You can redistribute this code and/or modify it under
7 //	the terms of the GNU General Public License as published
8 //	by the Free Software Foundation; either version 2 of the
9 //	License, or (at your option) any later version
10 // ==============================================================
11 
12 #include "menu_state_masterserver.h"
13 
14 #include "server_line.h"
15 #include "renderer.h"
16 #include "sound_renderer.h"
17 #include "core_data.h"
18 #include "config.h"
19 #include "menu_state_connected_game.h"
20 #include "menu_state_custom_game.h"
21 #include "menu_state_new_game.h"
22 #include "metrics.h"
23 #include "network_manager.h"
24 #include "network_message.h"
25 #include "auto_test.h"
26 #include "socket.h"
27 #include "masterserver_info.h"
28 #include <curl/curl.h>
29 #include "cache_manager.h"
30 #include "leak_dumper.h"
31 
32 namespace Glest{ namespace Game{
33 
34 DisplayMessageFunction MenuStateMasterserver::pCB_DisplayMessage = NULL;
35 
36 static string IRC_SERVER   = "irc.freenode.net";
37 static string IRC_CHANNEL  = "#megaglest-lobby";
38 
39 // =====================================================
40 // 	class MenuStateMasterserver
41 // =====================================================
42 
MenuStateMasterserver(Program * program,MainMenu * mainMenu)43 MenuStateMasterserver::MenuStateMasterserver(Program *program, MainMenu *mainMenu) :
44 	MenuState(program, mainMenu, "masterserver"), mutexIRCClient(new Mutex(CODE_AT_LINE))
45 {
46 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n\n******************** ENTERING MASTERSERVER MENU\n\n\n\n\n");
47 
48 	containerName = "MasterServer";
49 	masterserverParseErrorShown = false;
50 	updateFromMasterserverThread = NULL;
51 	ircClient = NULL;
52 	serverInfoString="empty";
53 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
54 
55 	Lang &lang= Lang::getInstance();
56 
57 	//Configure ConsolePosition
58 	consoleIRC.setYPos(60);
59 	consoleIRC.setFont(CoreData::getInstance().getMenuFontNormal());
60 	consoleIRC.setFont3D(CoreData::getInstance().getMenuFontNormal3D());
61 	consoleIRC.setLineHeight(18);
62 	consoleIRC.setOnlyChatMessagesInStoredLines(false);
63 
64 	serverLinesToRender=8;
65 	serverLinesLineHeight=25;
66 	serverLinesYBase=680;
67 
68 	userButtonsHeight=20;
69 	userButtonsWidth=150;
70 	userButtonsLineHeight=userButtonsHeight+2;
71 	userButtonsYBase=serverLinesYBase-(serverLinesToRender)*serverLinesLineHeight-90;
72 	userButtonsToRender=userButtonsYBase/userButtonsLineHeight;
73 	userButtonsXBase=1000-userButtonsWidth;
74 
75 	userScrollBar.init(1000-20,0,false,200,20);
76 	userScrollBar.setLength(userButtonsYBase+userButtonsLineHeight);
77 	userScrollBar.setElementCount(0);
78 	userScrollBar.setVisibleSize(userButtonsToRender);
79 	userScrollBar.setVisibleStart(0);
80 
81 	userButtonsXBase=1000-userButtonsWidth-userScrollBar.getW();
82 
83 	serverScrollBar.init(1000-20,serverLinesYBase-serverLinesLineHeight*(serverLinesToRender-1),false,200,20);
84 	serverScrollBar.setLength(serverLinesLineHeight*serverLinesToRender);
85 	serverScrollBar.setElementCount(0);
86 	serverScrollBar.setVisibleSize(serverLinesToRender);
87 	serverScrollBar.setVisibleStart(0);
88 
89 	lines[0].init(0, userButtonsYBase+userButtonsLineHeight+serverLinesLineHeight);
90 	lines[1].init(userButtonsXBase-5,0,5,userButtonsYBase+2*userButtonsLineHeight);
91 	lines[1].setHorizontal(false);
92 
93 	autoRefreshTime=0;
94 	playServerFoundSound=false;
95 	announcementLoaded=false;
96 
97 	mainMessageBox.registerGraphicComponent(containerName,"mainMessageBox");
98 	mainMessageBox.init(lang.getString("Ok"));
99 	mainMessageBox.setEnabled(false);
100 	mainMessageBoxState=0;
101 
102 	lastRefreshTimer= time(NULL);
103 
104 	// announcement
105 	announcementLabel.registerGraphicComponent(containerName,"announcementLabel");
106     announcementLabel.init(10, 730);
107     announcementLabel.setFont(CoreData::getInstance().getMenuFontBig());
108     announcementLabel.setFont3D(CoreData::getInstance().getMenuFontBig3D());
109     announcementLabel.setText("");
110 
111     // versionInfo
112     versionInfoLabel.registerGraphicComponent(containerName,"versionInfoLabel");
113     versionInfoLabel.init(10, 680);
114     versionInfoLabel.setFont(CoreData::getInstance().getMenuFontBig());
115     versionInfoLabel.setFont3D(CoreData::getInstance().getMenuFontBig3D());
116     versionInfoLabel.setText("");
117 
118 	// header
119 	labelTitle.registerGraphicComponent(containerName,"labelTitle");
120 	labelTitle.init(410, serverLinesYBase+45);
121 	labelTitle.setFont(CoreData::getInstance().getMenuFontBig());
122 	labelTitle.setFont3D(CoreData::getInstance().getMenuFontBig3D());
123 	labelTitle.setText(lang.getString("AvailableServers"));
124 
125 	if(Config::getInstance().getString("Masterserver","") == "") {
126 		labelTitle.setText("*** " + lang.getString("AvailableServers"));
127 	}
128 
129 	// bottom
130 	int buttonPos=230;
131 
132 	// Titles for current games - START
133 	int lineIndex = 0;
134 	int lineOffset=25*lineIndex;
135 	int i=5;
136 	int startOffset=serverLinesYBase+23;
137 
138 	//general info:
139 	//i+=10;
140 	glestVersionLabel.registerGraphicComponent(containerName,"glestVersionLabel");
141 	glestVersionLabel.init(i,startOffset-lineOffset);
142 	glestVersionLabel.setText(lang.getString("MGVersion"));
143 
144 	i+=80;
145 	platformLabel.registerGraphicComponent(containerName,"platformLabel");
146 	platformLabel.init(i+15,startOffset-lineOffset);
147 	platformLabel.setText(lang.getString("MGPlatform"));
148 
149 //	i+=50;
150 //	binaryCompileDateLabel.registerGraphicComponent(containerName,"binaryCompileDateLabel");
151 //	binaryCompileDateLabel.init(i,startOffset-lineOffset);
152 //	binaryCompileDateLabel.setText(lang.getString("MGBuildDateTime"));
153 
154 	//game info:
155 	i+=120;
156 	serverTitleLabel.registerGraphicComponent(containerName,"serverTitleLabel");
157 	serverTitleLabel.init(i,startOffset-lineOffset);
158 	serverTitleLabel.setText(lang.getString("MGGameTitle"));
159 
160 	i+=170;
161 	countryLabel.registerGraphicComponent(containerName,"countryLabel");
162 	countryLabel.init(i-10,startOffset-lineOffset);
163 	countryLabel.setText(lang.getString("MGGameCountry"));
164 
165 	i+=60;
166 
167 //	ipAddressLabel.registerGraphicComponent(containerName,"ipAddressLabel");
168 //	ipAddressLabel.init(i,startOffset-lineOffset);
169 //	ipAddressLabel.setText(lang.getString("MGGameIP"));
170 //	i+=100;
171 
172 	//game setup info:
173 	techLabel.registerGraphicComponent(containerName,"techLabel");
174 	techLabel.init(i,startOffset-lineOffset);
175 	techLabel.setText(lang.getString("TechTree"));
176 
177 	i+=165;
178 	mapLabel.registerGraphicComponent(containerName,"mapLabel");
179 	mapLabel.init(i,startOffset-lineOffset);
180 	mapLabel.setText(lang.getString("Map"));
181 
182 	i+=95;
183 //	tilesetLabel.registerGraphicComponent(containerName,"tilesetLabel");
184 //	tilesetLabel.init(i,startOffset-lineOffset);
185 //	tilesetLabel.setText(lang.getString("Tileset"));
186 //	i+=100;
187 
188 	activeSlotsLabel.registerGraphicComponent(containerName,"activeSlotsLabel");
189 	activeSlotsLabel.init(i,startOffset-lineOffset);
190 	activeSlotsLabel.setText(lang.getString("MGGameSlots"));
191 
192 	i+=50;
193 	//externalConnectPort.registerGraphicComponent(containerName,"externalConnectPort");
194 	//externalConnectPort.init(i,startOffset-lineOffset);
195 	//externalConnectPort.setText(lang.getString("Port"));
196 
197 	i+=30;
198 	statusLabel.registerGraphicComponent(containerName,"statusLabel");
199 	statusLabel.init(i+5,startOffset-lineOffset);
200 	statusLabel.setText(lang.getString("MGGameStatus"));
201 
202 	i+=130;
203 	selectButton.registerGraphicComponent(containerName,"selectButton");
204 	selectButton.init(i-5, startOffset-lineOffset);
205 	selectButton.setText(lang.getString("MGJoinGameSlots"));
206 
207 	// Titles for current games - END
208 
209 	buttonReturn.registerGraphicComponent(containerName,"buttonReturn");
210     buttonReturn.init(50, buttonPos, 150);
211 
212     buttonCreateGame.registerGraphicComponent(containerName,"buttonCreateGame");
213     buttonCreateGame.init(275, buttonPos, 150);
214 
215     buttonRefresh.registerGraphicComponent(containerName,"buttonRefresh");
216     buttonRefresh.init(500, buttonPos, 150);
217 
218 	buttonRefresh.setText(lang.getString("RefreshList"));
219 	buttonReturn.setText(lang.getString("Return"));
220 	buttonCreateGame.setText(lang.getString("HostGame"));
221 	labelAutoRefresh.setText(lang.getString("AutoRefreshRate"));
222 
223 	labelAutoRefresh.registerGraphicComponent(containerName,"labelAutoRefresh");
224 	labelAutoRefresh.init(750,buttonPos+30);
225 
226 	listBoxAutoRefresh.registerGraphicComponent(containerName,"listBoxAutoRefresh");
227 	listBoxAutoRefresh.init(750,buttonPos);
228 	listBoxAutoRefresh.pushBackItem(lang.getString("Off"));
229 	listBoxAutoRefresh.pushBackItem("10 s");
230 	listBoxAutoRefresh.pushBackItem("20 s");
231 	listBoxAutoRefresh.pushBackItem("30 s");
232 	listBoxAutoRefresh.setSelectedItemIndex(2);
233 	autoRefreshTime=10*listBoxAutoRefresh.getSelectedItemIndex();
234 
235 	ircOnlinePeopleLabel.registerGraphicComponent(containerName,"ircOnlinePeopleLabel");
236 	ircOnlinePeopleLabel.init(userButtonsXBase,userButtonsYBase+userButtonsLineHeight);
237 	ircOnlinePeopleLabel.setText(lang.getString("IRCPeopleOnline"));
238 
239 	ircOnlinePeopleStatusLabel.registerGraphicComponent(containerName,"ircOnlinePeopleStatusLabel");
240 	ircOnlinePeopleStatusLabel.init(userButtonsXBase,userButtonsYBase+userButtonsLineHeight-20);
241 	ircOnlinePeopleStatusLabel.setText("");
242 
243 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
244 
245 	NetworkManager::getInstance().end();
246 	NetworkManager::getInstance().init(nrClient);
247 
248 	//console.addLine(lang.getString("ToSwitchOffMusicPress")+" - \""+configKeys.getCharKey("ToggleMusic")+"\"");
249 
250 	GraphicComponent::applyAllCustomProperties(containerName);
251 
252     char szIRCNick[80]="";
253 	Chrono seed(true);
254 	srand((unsigned int)seed.getCurTicks());
255 
256     int randomNickId = rand() % 999;
257     string netPlayerName=Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str());
258     string ircname=netPlayerName.substr(0,9);
259     snprintf(szIRCNick,80,"MG_%s_%d",ircname.c_str(),randomNickId);
260     normalizeNick(szIRCNick);
261 
262     currentIrcNick=ircname;
263     consoleIRC.setStringToHighlight(currentIrcNick);
264 
265     lines[2].init(0,consoleIRC.getYPos()-10,userButtonsXBase,5);
266     chatManager.init(&consoleIRC, -1, true, szIRCNick);
267     chatManager.setXPos(0);
268     chatManager.setYPos(consoleIRC.getYPos()-20);
269     chatManager.setFont(CoreData::getInstance().getMenuFontNormal());
270     chatManager.setFont3D(CoreData::getInstance().getMenuFontNormal3D());
271 
272 	needUpdateFromServer = true;
273 
274 	static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
275 	updateFromMasterserverThread = new SimpleTaskThread(this,0,100);
276 	updateFromMasterserverThread->setUniqueID(mutexOwnerId);
277 	updateFromMasterserverThread->start();
278 
279     if(Config::getInstance().getString("IRCServer","") != "") {
280     	IRC_SERVER = Config::getInstance().getString("IRCServer");
281     }
282    	ircArgs.push_back(IRC_SERVER);
283 
284     if(Config::getInstance().getString("IRCNick","") != "") {
285     	ircArgs.push_back(Config::getInstance().getString("IRCNick"));
286     }
287     else {
288     	ircArgs.push_back(szIRCNick);
289     }
290 
291     if(Config::getInstance().getString("IRCChannel","") != "") {
292     	IRC_CHANNEL = Config::getInstance().getString("IRCChannel");
293     }
294    	ircArgs.push_back(IRC_CHANNEL);
295 
296     if(Config::getInstance().getString("IRCUsername","") != "") {
297     	ircArgs.push_back(Config::getInstance().getString("IRCUsername"));
298     }
299     else {
300     	ircArgs.push_back(szIRCNick);
301     }
302     if(Config::getInstance().getString("IRCPassword","") != "") {
303     	ircArgs.push_back("identify " + Config::getInstance().getString("IRCPassword"));
304     }
305     else {
306     	ircArgs.push_back("");
307     }
308 
309     MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
310 
311     if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 IRCCLient Cache check\n");
312     IRCThread * &ircThread = CacheManager::getCachedItem< IRCThread * >(GameConstants::ircClientCacheLookupKey);
313 
314     // Playername changed so restart the IRC Thread
315     if(ircThread != NULL && netPlayerName != ircThread->getPlayerName()) {
316     	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
317     	ircThread->leaveChannel();
318     	ircThread->setCallbackObj(NULL);
319     	ircThread->signalQuit();
320         if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
321         ircThread = NULL;
322     }
323 
324     if(ircThread == NULL) {
325     	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 IRCCLient Cache check\n");
326 
327     	static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
328     	ircThread = new IRCThread(ircArgs,this);
329     	ircClient = ircThread;
330     	ircClient->setUniqueID(mutexOwnerId);
331     	ircClient->setPlayerName(netPlayerName);
332 		ircClient->start();
333     }
334     else {
335     	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#3 IRCCLient Cache check\n");
336     	ircClient = ircThread;
337     	ircClient->setCallbackObj(this);
338     	ircClient->joinChannel();
339     }
340 
341     if(netPlayerName=="newbie"){
342     	showMessageBox(lang.getString("PlayerNameNotSetPrompt"),lang.getString("PlayerNameNotSetTitle"),false);
343     }
344     //showMessageBox("Go back and set your name in the game options!\n\nAt the moment you are just called >>newbie<< !","Player name not set!",false);
345 
346     if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
347 }
348 
reloadUI()349 void MenuStateMasterserver::reloadUI() {
350 	Lang &lang= Lang::getInstance();
351 
352 	console.resetFonts();
353 	consoleIRC.setFont(CoreData::getInstance().getMenuFontNormal());
354 	consoleIRC.setFont3D(CoreData::getInstance().getMenuFontNormal3D());
355 
356 	mainMessageBox.init(lang.getString("Ok"));
357 
358     announcementLabel.setFont(CoreData::getInstance().getMenuFontBig());
359     announcementLabel.setFont3D(CoreData::getInstance().getMenuFontBig3D());
360 
361     versionInfoLabel.setFont(CoreData::getInstance().getMenuFontBig());
362     versionInfoLabel.setFont3D(CoreData::getInstance().getMenuFontBig3D());
363 
364 	labelTitle.setFont(CoreData::getInstance().getMenuFontBig());
365 	labelTitle.setFont3D(CoreData::getInstance().getMenuFontBig3D());
366 	labelTitle.setText(lang.getString("AvailableServers"));
367 
368 	if(Config::getInstance().getString("Masterserver","") == "") {
369 		labelTitle.setText("*** " + lang.getString("AvailableServers"));
370 	}
371 
372 	glestVersionLabel.setText(lang.getString("MGVersion"));
373 
374 	platformLabel.setText(lang.getString("MGPlatform"));
375 
376 	serverTitleLabel.setText(lang.getString("MGGameTitle"));
377 
378 	countryLabel.setText(lang.getString("MGGameCountry"));
379 
380 	techLabel.setText(lang.getString("TechTree"));
381 
382 	mapLabel.setText(lang.getString("Map"));
383 
384 	activeSlotsLabel.setText(lang.getString("MGGameSlots"));
385 
386 	//externalConnectPort.setText(lang.getString("Port"));
387 
388 	statusLabel.setText(lang.getString("MGGameStatus"));
389 
390 	selectButton.setText(lang.getString("MGJoinGameSlots"));
391 
392 	// Titles for current games - END
393 
394 	buttonRefresh.setText(lang.getString("RefreshList"));
395 	buttonReturn.setText(lang.getString("Return"));
396 	buttonCreateGame.setText(lang.getString("HostGame"));
397 	labelAutoRefresh.setText(lang.getString("AutoRefreshRate"));
398 
399 	ircOnlinePeopleLabel.setText(lang.getString("IRCPeopleOnline"));
400 
401     chatManager.setFont(CoreData::getInstance().getMenuFontNormal());
402     chatManager.setFont3D(CoreData::getInstance().getMenuFontNormal3D());
403 
404 	GraphicComponent::reloadFontsForRegisterGraphicComponents(containerName);
405 }
406 
setConsolePos(int yPos)407 void MenuStateMasterserver::setConsolePos(int yPos){
408 		consoleIRC.setYPos(yPos);
409 		lines[2].setY(consoleIRC.getYPos()-10);
410 		chatManager.setYPos(consoleIRC.getYPos()-20);
411 }
412 
setButtonLinePosition(int pos)413 void MenuStateMasterserver::setButtonLinePosition(int pos){
414     buttonReturn.setY(pos);
415     buttonCreateGame.setY(pos);
416     buttonRefresh.setY(pos);
417 	labelAutoRefresh.setY(pos+30);
418 	listBoxAutoRefresh.setY(pos);
419 }
420 
IRC_CallbackEvent(IRCEventType evt,const char * origin,const char ** params,unsigned int count)421 void MenuStateMasterserver::IRC_CallbackEvent(IRCEventType evt, const char* origin, const char **params, unsigned int count) {
422     MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
423     if(ircClient != NULL) {
424         if(evt == IRC_evt_exitThread) {
425         	ircClient->leaveChannel();
426             ircClient->setCallbackObj(NULL);
427 
428             ircClient = NULL;
429         }
430         else if(evt == IRC_evt_chatText) {
431             //printf ("===> IRC: '%s' said in channel %s: %s\n",origin ? origin : "someone",params[0], params[1] );
432 
433             char szBuf[8096]="";
434             snprintf(szBuf,8096,"%s: %s",origin ? origin : "someone",params[1]);
435             string helpSTr=szBuf;
436         	if(helpSTr.find(currentIrcNick)!=string::npos){
437         		CoreData &coreData= CoreData::getInstance();
438         		SoundRenderer &soundRenderer= SoundRenderer::getInstance();
439 
440         		soundRenderer.playFx(coreData.getHighlightSound());
441         	}
442             consoleIRC.addLine(szBuf);
443         }
444     }
445 }
446 
cleanup()447 void MenuStateMasterserver::cleanup() {
448 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
449 
450     MutexSafeWrapper safeMutex((updateFromMasterserverThread != NULL ? updateFromMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
451     needUpdateFromServer = false;
452     safeMutex.ReleaseLock();
453 
454     if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
455 
456 //    if(updateFromMasterserverThread != NULL &&
457 //        updateFromMasterserverThread->canShutdown(true) == true) {
458 //        if(updateFromMasterserverThread->shutdownAndWait() == true) {
459 //            delete updateFromMasterserverThread;
460 //        }
461 //    }
462 //    updateFromMasterserverThread = NULL;
463 	if(updateFromMasterserverThread != NULL) {
464 		updateFromMasterserverThread->signalQuit();
465 	}
466 	if(updateFromMasterserverThread != NULL && updateFromMasterserverThread->canShutdown(false) == true  &&
467 			updateFromMasterserverThread->getRunningStatus() == false) {
468 		//printf("#2 Ending client SLOT: %d\n",playerIndex);
469 
470 		if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
471         delete updateFromMasterserverThread;
472         if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
473 	}
474 	//else if(BaseThread::shutdownAndWait(slotThreadWorker) == true) {
475 	else if(updateFromMasterserverThread != NULL && updateFromMasterserverThread->canShutdown(true) == true) {
476 		if(updateFromMasterserverThread->getRunningStatus() == false) {
477 			//printf("#3 Ending client SLOT: %d\n",playerIndex);
478 			if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
479 			delete updateFromMasterserverThread;
480 			if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
481 		}
482 		else {
483 			updateFromMasterserverThread->setDeleteSelfOnExecutionDone(true);
484 			updateFromMasterserverThread->setDeleteAfterExecute(true);
485 		}
486 	}
487 	//printf("#4 Ending client SLOT: %d\n",playerIndex);
488 	updateFromMasterserverThread = NULL;
489 
490     if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
491 
492 	clearServerLines();
493 	clearUserButtons();
494 
495     MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
496     if(ircClient != NULL) {
497     	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
498 
499     	ircClient->leaveChannel();
500         ircClient->setCallbackObj(NULL);
501         //ircClient->signalQuit();
502         if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
503         ircClient = NULL;
504     }
505 
506     if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
507 }
508 
~MenuStateMasterserver()509 MenuStateMasterserver::~MenuStateMasterserver() {
510 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
511 
512 	cleanup();
513 
514 	delete mutexIRCClient;
515 	mutexIRCClient = NULL;
516 
517 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
518 }
519 
clearServerLines()520 void MenuStateMasterserver::clearServerLines() {
521 	while(!serverLines.empty()) {
522 		delete serverLines.back();
523 		serverLines.pop_back();
524 	}
525 }
526 
clearUserButtons()527 void MenuStateMasterserver::clearUserButtons() {
528 	while(!userButtons.empty()){
529 		delete userButtons.back();
530 		userButtons.pop_back();
531 	}
532 }
533 
mouseClick(int x,int y,MouseButton mouseButton)534 void MenuStateMasterserver::mouseClick(int x, int y, MouseButton mouseButton){
535 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
536 
537 	CoreData &coreData= CoreData::getInstance();
538 	SoundRenderer &soundRenderer= SoundRenderer::getInstance();
539 
540 	if(mainMessageBox.getEnabled()){
541 		int button= 0;
542 		if(mainMessageBox.mouseClick(x, y, button)) {
543 			soundRenderer.playFx(coreData.getClickSoundA());
544 			if(button == 0) {
545 				mainMessageBox.setEnabled(false);
546 			}
547 		}
548 	}
549 	else if(userScrollBar.mouseClick(x, y)){
550 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
551 			soundRenderer.playFx(coreData.getClickSoundA());
552 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
553 	    }
554 	else if(serverScrollBar.mouseClick(x, y)){
555 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
556 			soundRenderer.playFx(coreData.getClickSoundA());
557 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
558 	    }
559 	else if(buttonRefresh.mouseClick(x, y)){
560 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
561 
562 		MutexSafeWrapper safeMutex((updateFromMasterserverThread != NULL ? updateFromMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
563 		soundRenderer.playFx(coreData.getClickSoundB());
564 		needUpdateFromServer = true;
565 
566 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
567     }
568     else if(buttonReturn.mouseClick(x, y)){
569     	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
570 
571 		soundRenderer.playFx(coreData.getClickSoundA());
572 
573 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
574 		if (ircClient != NULL && ircClient->isConnected() == true
575 					&& ircClient->getHasJoinedChannel() == true) {
576 			ircClient->SendIRCCmdMessage(IRC_CHANNEL, "   <<   left the lobby");
577 			sleep(30);
578 		}
579         cleanup();
580 
581         if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
582 
583 		mainMenu->setState(new MenuStateNewGame(program, mainMenu));
584 
585 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
586     }
587     else if(buttonCreateGame.mouseClick(x, y)){
588     	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
589 
590     	MutexSafeWrapper safeMutex((updateFromMasterserverThread != NULL ? updateFromMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
591 		soundRenderer.playFx(coreData.getClickSoundB());
592 		needUpdateFromServer = false;
593 		safeMutex.ReleaseLock();
594 
595 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
596 		if (ircClient != NULL && ircClient->isConnected() == true
597 					&& ircClient->getHasJoinedChannel() == true) {
598 			ircClient->SendIRCCmdMessage(IRC_CHANNEL, "   <<   tries to create a game");
599 			sleep(30);
600 		}
601         cleanup();
602         if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
603 
604 		mainMenu->setState(new MenuStateCustomGame(program, mainMenu,true,pMasterServer));
605 
606 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
607     }
608     else if(listBoxAutoRefresh.mouseClick(x, y)){
609     	MutexSafeWrapper safeMutex((updateFromMasterserverThread != NULL ? updateFromMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
610 		soundRenderer.playFx(coreData.getClickSoundA());
611 		autoRefreshTime=10*listBoxAutoRefresh.getSelectedItemIndex();
612     }
613     else {
614     	MutexSafeWrapper safeMutex((updateFromMasterserverThread != NULL ? updateFromMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
615     	bool clicked=false;
616     	if(!clicked && serverScrollBar.getElementCount()!=0){
617     		for(int i = serverScrollBar.getVisibleStart(); i <= serverScrollBar.getVisibleEnd(); ++i) {
618 				if(serverLines[i]->buttonMouseClick(x, y)) {
619 					if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
620 					clicked=true;
621 					soundRenderer.playFx(coreData.getClickSoundB());
622 					string connectServerIP = serverLines[i]->getMasterServerInfo()->getIpAddress();
623 					int connectServerPort = serverLines[i]->getMasterServerInfo()->getExternalConnectPort();
624 					bool connected=connectToServer(connectServerIP,connectServerPort);
625 					if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
626 					safeMutex.ReleaseLock();
627 					if(connected){
628 						soundRenderer.playFx(coreData.getClickSoundB());
629 
630 						if (ircClient != NULL && ircClient->isConnected() == true
631 									&& ircClient->getHasJoinedChannel() == true) {
632 							ircClient->SendIRCCmdMessage(IRC_CHANNEL, "   <<   is connecting to '"+serverLines[i]->getMasterServerInfo()->getServerTitle()+"'");
633 							sleep(30);
634 						}
635 						cleanup();
636 						if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
637 						mainMenu->setState(new MenuStateConnectedGame(program, mainMenu,jmMasterserver));
638 					}
639 					break;
640 				}
641     		}
642     	}
643 	    if(!clicked && userScrollBar.getElementCount()!=0){
644 	    	for(int i = userScrollBar.getVisibleStart(); i <= userScrollBar.getVisibleEnd(); ++i) {
645 	       		if(userButtons[i]->getEnabled() == true && userButtons[i]->mouseClick(x, y)) {
646 	       			//clicked=true;
647 	     			if(!chatManager.getEditEnabled())
648 	     			{
649 	     				chatManager.switchOnEdit();
650 	     				chatManager.addText(userButtons[i]->getText()+" ");
651 	     			}
652 	     			else
653 	     			{
654 	     				chatManager.addText(userButtons[i]->getText());
655 	     			}
656 	       			break;
657 	       		}
658 	    	}
659 	    }
660     }
661 }
662 
mouseUp(int x,int y,const MouseButton mouseButton)663 void MenuStateMasterserver::mouseUp(int x, int y, const MouseButton mouseButton){
664 	if (mouseButton == mbLeft) {
665 		userScrollBar.mouseUp(x, y);
666 		serverScrollBar.mouseUp(x, y);
667 	}
668 }
669 
mouseMove(int x,int y,const MouseState * ms)670 void MenuStateMasterserver::mouseMove(int x, int y, const MouseState *ms){
671 	MutexSafeWrapper safeMutex((updateFromMasterserverThread != NULL ? updateFromMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
672 
673 	if (mainMessageBox.getEnabled()) {
674 		mainMessageBox.mouseMove(x, y);
675 	}
676     buttonRefresh.mouseMove(x, y);
677     buttonReturn.mouseMove(x, y);
678     buttonCreateGame.mouseMove(x, y);
679     if (ms->get(mbLeft)) {
680 		userScrollBar.mouseDown(x, y);
681 		serverScrollBar.mouseDown(x, y);
682 	} else {
683 		userScrollBar.mouseMove(x, y);
684 		serverScrollBar.mouseMove(x, y);
685 	}
686     listBoxAutoRefresh.mouseMove(x, y);
687 
688     if(serverScrollBar.getElementCount()!=0 ) {
689     	for(int i = serverScrollBar.getVisibleStart(); i <= serverScrollBar.getVisibleEnd(); ++i) {
690     		serverLines[i]->buttonMouseMove(x, y);
691     	}
692     }
693     if(userScrollBar.getElementCount()!=0 ) {
694     	for(int i = userScrollBar.getVisibleStart(); i <= userScrollBar.getVisibleEnd(); ++i) {
695     		if(userButtons[i]->getEnabled() == true) {
696     			userButtons[i]->mouseMove(x, y);
697     		}
698     	}
699     }
700 
701 }
702 
render()703 void MenuStateMasterserver::render(){
704 	Renderer &renderer= Renderer::getInstance();
705 
706 	MutexSafeWrapper safeMutex((updateFromMasterserverThread != NULL ? updateFromMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
707 	if(mainMessageBox.getEnabled()) {
708 		renderer.renderMessageBox(&mainMessageBox);
709 	}
710 	else
711 	{
712 		renderer.renderLabel(&labelTitle,&GREEN);
713 		renderer.renderLabel(&announcementLabel,&YELLOW);
714 		renderer.renderLabel(&versionInfoLabel);
715 
716 		// Render titles for server games listed
717 		const Vec4f titleLabelColor = CYAN;
718 
719 		//general info:
720 		renderer.renderLabel(&glestVersionLabel,&titleLabelColor);
721 		renderer.renderLabel(&platformLabel,&titleLabelColor);
722 		//renderer.renderLabel(&binaryCompileDateLabel,&titleLabelColor);
723 
724 		//game info:
725 		renderer.renderLabel(&serverTitleLabel,&titleLabelColor);
726 		renderer.renderLabel(&countryLabel,&titleLabelColor);
727 		renderer.renderLabel(&statusLabel,&titleLabelColor);
728 		//renderer.renderLabel(&ipAddressLabel,&titleLabelColor);
729 
730 		//game setup info:
731 		renderer.renderLabel(&techLabel,&titleLabelColor);
732 		renderer.renderLabel(&mapLabel,&titleLabelColor);
733 		//renderer.renderLabel(&tilesetLabel,&titleLabelColor);
734 		renderer.renderLabel(&activeSlotsLabel,&titleLabelColor);
735 		//renderer.renderLabel(&externalConnectPort,&titleLabelColor);
736 		renderer.renderLabel(&selectButton,&titleLabelColor);
737 
738 		Lang &lang= Lang::getInstance();
739 		MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
740         if(ircClient != NULL &&
741            ircClient->isConnected() == true &&
742            ircClient->getHasJoinedChannel() == true) {
743             const Vec4f titleLabelColor = GREEN;
744 
745             if(ircOnlinePeopleStatusLabel.getText() != "") {
746             	ircOnlinePeopleStatusLabel.setText("");
747             }
748 
749             renderer.renderLabel(&ircOnlinePeopleLabel,&titleLabelColor);
750             //renderer.renderLabel(&ircOnlinePeopleStatusLabel,&titleLabelColor);
751         }
752         else {
753             const Vec4f titleLabelColor = RED;
754 
755             if(ircOnlinePeopleStatusLabel.getText() != lang.getString("Connecting")) {
756             	ircOnlinePeopleStatusLabel.setText(lang.getString("Connecting"));
757             }
758 
759             renderer.renderLabel(&ircOnlinePeopleLabel,&titleLabelColor);
760             renderer.renderLabel(&ircOnlinePeopleStatusLabel,&titleLabelColor);
761         }
762         safeMutexIRCPtr.ReleaseLock();
763 
764         //const Vec4f titleLabelColorList = YELLOW;
765 
766 		if(serverScrollBar.getElementCount()!=0 ) {
767 			for(int i = serverScrollBar.getVisibleStart(); i <= serverScrollBar.getVisibleEnd(); ++i) {
768 				serverLines[i]->render();
769 			}
770 		}
771 		renderer.renderScrollBar(&serverScrollBar);
772 
773 	    for(int i = 0; i < (int)sizeof(lines) / (int)sizeof(lines[0]); ++i){
774 	    	renderer.renderLine(&lines[i]);
775 	    }
776 	    renderer.renderButton(&buttonRefresh);
777 		renderer.renderButton(&buttonReturn);
778 		renderer.renderLabel(&labelAutoRefresh);
779 		renderer.renderButton(&buttonCreateGame);
780 		renderer.renderListBox(&listBoxAutoRefresh);
781 
782 		if(userScrollBar.getElementCount()!=0 ) {
783 			for(int i = userScrollBar.getVisibleStart(); i <= userScrollBar.getVisibleEnd(); ++i) {
784 				renderer.renderButton(userButtons[i]);
785 			}
786 		}
787 		renderer.renderScrollBar(&userScrollBar);
788 		 if(ircClient != NULL &&
789 		           ircClient->isConnected() == true &&
790 		           ircClient->getHasJoinedChannel() == true) {
791 					 renderer.renderChatManager(&chatManager);
792 		        }
793 		renderer.renderConsole(&consoleIRC,consoleStoredOnly,21);
794 
795 	}
796 	if(program != NULL) program->renderProgramMsgBox();
797 }
798 
update()799 void MenuStateMasterserver::update() {
800 	MutexSafeWrapper safeMutex((updateFromMasterserverThread != NULL ? updateFromMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
801 	if(autoRefreshTime!=0 && difftime(time(NULL),lastRefreshTimer) >= autoRefreshTime ) {
802 		needUpdateFromServer = true;
803 		lastRefreshTimer= time(NULL);
804 	}
805 
806 	// calculate button linepos:
807 	setButtonLinePosition(serverLinesYBase-(serverLinesToRender)*serverLinesLineHeight-30);
808 
809 	if(playServerFoundSound)
810 	{
811 		SoundRenderer::getInstance().playFx(CoreData::getInstance().getAttentionSound());
812 		//switch on music again!!
813 		Config &config = Config::getInstance();
814 		float configVolume = (config.getInt("SoundVolumeMusic") / 100.f);
815 		CoreData::getInstance().getMenuMusic()->setVolume(configVolume);
816 
817 		playServerFoundSound=false;
818 	}
819 
820 	//console.update();
821 
822     //call the chat manager
823     chatManager.updateNetwork();
824 
825     //console
826     consoleIRC.update();
827 
828     MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
829     if(ircClient != NULL) {
830         std::vector<string> nickList = ircClient->getNickList();
831 
832     	if(currentIrcNick != ircClient->getNick()) {
833     		currentIrcNick = ircClient->getNick();
834     		consoleIRC.setStringToHighlight(currentIrcNick);
835     	}
836 
837         bool isNew=false;
838         //check if there is something new
839         if( oldNickList.size() != nickList.size()) {
840         	isNew=true;
841         }
842         else {
843         	for(unsigned int i = 0; i < nickList.size(); ++i) {
844         		if(nickList[i] != oldNickList[i]) {
845         			isNew=true;
846         			break;
847         		}
848         	}
849         }
850 
851         if(isNew) {
852 	        clearUserButtons();
853 	        for(int i = 0; i < (int)nickList.size(); ++i) {
854 	                GraphicButton *button=new GraphicButton();
855 	                button->init(userButtonsXBase,userButtonsYBase,userButtonsWidth,userButtonsHeight);
856 	                //button->init(userButtonsXBase,userButtonsYBase-userButtonsLineHeight*i,userButtonsWidth,userButtonsHeight);
857 					button->setFont(CoreData::getInstance().getDisplayFontSmall());
858 					button->setFont3D(CoreData::getInstance().getDisplayFontSmall3D());
859 					button->setText(nickList[i]);
860 					if(strncmp(&nickList[i][0],"MG_",3) != 0 || &nickList[i][0] == currentIrcNick) {
861 						button->setEnabled(false);
862 						button->setEditable(false);
863 						button->setCustomTexture(CoreData::getInstance().getCustomTexture());
864 						button->setUseCustomTexture(true);
865 					}
866 
867 	                userButtons.push_back(button);
868 	        }
869 	        userScrollBar.setElementCount((int)userButtons.size());
870 	        oldNickList = nickList;
871 	        chatManager.setAutoCompleteTextList(oldNickList);
872         }
873         if(userScrollBar.getElementCount()!=0 ) {
874         	for(int i = userScrollBar.getVisibleStart(); i <= userScrollBar.getVisibleEnd(); ++i) {
875         		userButtons[i]->setY(userButtonsYBase-userButtonsLineHeight*(i-userScrollBar.getVisibleStart()));
876         	}
877         }
878     }
879     safeMutexIRCPtr.ReleaseLock();
880     if(serverInfoString!="empty")
881     {
882     	rebuildServerLines(serverInfoString);
883     	serverInfoString="empty";
884     }
885 
886     serverScrollBar.setElementCount((int)serverLines.size());
887 	if(serverScrollBar.getElementCount()!=0 ) {
888 		for(int i = serverScrollBar.getVisibleStart(); i <= serverScrollBar.getVisibleEnd(); ++i) {
889 			serverLines[i]->setY(serverLinesYBase-serverLinesLineHeight*(i-serverScrollBar.getVisibleStart()));
890 		}
891 	}
892 
893 	if(threadedErrorMsg != "") {
894 		std::string sError = threadedErrorMsg;
895 		threadedErrorMsg = "";
896 
897 		if(pCB_DisplayMessage != NULL) {
898 			pCB_DisplayMessage(sError.c_str(),false);
899 		}
900 		else {
901 			throw megaglest_runtime_error(sError.c_str());
902 		}
903 	}
904 }
905 
simpleTask(BaseThread * callingThread,void * userdata)906 void MenuStateMasterserver::simpleTask(BaseThread *callingThread,void *userdata) {
907 	if(callingThread->getQuitStatus() == true) {
908 		return;
909 	}
910 	MutexSafeWrapper safeMutex(callingThread->getMutexThreadObjectAccessor(),string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
911 	bool needUpdate = needUpdateFromServer;
912 
913 	if(needUpdate == true) {
914         try {
915 
916             if(callingThread->getQuitStatus() == true) {
917                 return;
918             }
919 
920             needUpdateFromServer = false;
921 
922             if(announcementLoaded == false) {
923                 string announcementURL = Config::getInstance().getString("AnnouncementURL","http://master.megaglest.org/files/announcement.txt");
924                 if(announcementURL != "") {
925 
926                     safeMutex.ReleaseLock(true);
927                     CURL *handle = SystemFlags::initHTTP();
928 					std::string announcementTxt = SystemFlags::getHTTP(announcementURL,handle);
929 					SystemFlags::cleanupHTTP(&handle);
930                     if(callingThread->getQuitStatus() == true) {
931                         return;
932                     }
933                     safeMutex.Lock();
934 
935                     if(StartsWith(announcementTxt,"Announcement from Masterserver:") == true) {
936                         int newlineCount=0;
937                         size_t lastIndex=0;
938 
939                         //announcementLabel.setText(announcementTxt);
940                         consoleIRC.addLine(announcementTxt, true, Vec3f(1.0f,1.0f,0.0f));
941 
942                         while(true) {
943                             lastIndex=announcementTxt.find("\n",lastIndex+1);
944                             if(lastIndex==string::npos) {
945                                 break;
946                             }
947                             else {
948                                 newlineCount++;
949                             }
950                         }
951                         newlineCount--;// remove my own line
952                         for( int i=0; i< newlineCount;++i ) {
953                             consoleIRC.addLine("");
954                         }
955                     }
956                 }
957                 consoleIRC.addLine("---------------------------------------------");
958                 string versionURL = Config::getInstance().getString("VersionURL","http://master.megaglest.org/files/versions/")+glestVersionString+".txt";
959                 //printf("\nversionURL=%s\n",versionURL.c_str());
960                 if(versionURL != "") {
961                     safeMutex.ReleaseLock(true);
962                     CURL *handle = SystemFlags::initHTTP();
963                     std::string versionTxt = SystemFlags::getHTTP(versionURL,handle);
964 					SystemFlags::cleanupHTTP(&handle);
965                     if(callingThread->getQuitStatus() == true) {
966                         return;
967                     }
968                     safeMutex.Lock();
969 
970                     if(StartsWith(versionTxt,"Version info:") == true) {
971                         int newlineCount=0;
972                         size_t lastIndex=0;
973 
974                         //versionInfoLabel.setText(versionTxt);
975                         consoleIRC.addLine(versionTxt, true, Vec3f(1.0f,0.0f,0.0f));
976 
977                         while(true) {
978                             lastIndex=versionTxt.find("\n",lastIndex+1);
979                             if(lastIndex==string::npos) {
980                                 break;
981                             }
982                             else {
983                                 newlineCount++;
984                             }
985                         }
986                         newlineCount--;// remove my own line
987                         for( int i=0; i< newlineCount;++i ) {
988                             consoleIRC.addLine("");
989                         }
990                     }
991                 }
992                 consoleIRC.addLine("---------------------------------------------");
993                 // write hint to console:
994                 Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
995                 consoleIRC.addLine(Lang::getInstance().getString("ToSwitchOffMusicPress")+" - \""+configKeys.getString("ToggleMusic")+"\"");
996 
997                 announcementLoaded=true;
998             }
999 
1000             //Lang &lang= Lang::getInstance();
1001             try {
1002                 if(Config::getInstance().getString("Masterserver","") != "") {
1003 
1004                     safeMutex.ReleaseLock(true);
1005 					CURL *handle = SystemFlags::initHTTP();
1006 
1007 					string playerUUID = "?uuid=" + SystemFlags::escapeURL(Config::getInstance().getString("PlayerId",""));
1008 
1009 					string baseURL = Config::getInstance().getString("Masterserver");
1010 		    		if(baseURL != "") {
1011 		    			endPathWithSlash(baseURL,false);
1012 		    		}
1013 
1014 					std::string localServerInfoString = SystemFlags::getHTTP(baseURL + "showServersForGlest.php" + playerUUID,handle);
1015 					SystemFlags::cleanupHTTP(&handle);
1016                     if(callingThread->getQuitStatus() == true) {
1017                         return;
1018                     }
1019                     safeMutex.Lock();
1020 
1021                     serverInfoString=localServerInfoString;
1022                 }
1023             }
1024             catch(const exception &ex) {
1025                 serverInfoString=ex.what();
1026                 SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line %d] error during Internet game status update: [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
1027             }
1028         }
1029         catch(const exception &e){
1030             SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
1031             if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d, error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
1032             threadedErrorMsg = e.what();
1033         }
1034 	}
1035 }
1036 
rebuildServerLines(const string & serverInfo)1037 void MenuStateMasterserver::rebuildServerLines(const string &serverInfo) {
1038 	int numberOfOldServerLines = (int)serverLines.size();
1039 	clearServerLines();
1040     Lang &lang= Lang::getInstance();
1041     try {
1042 		if(serverInfo != "") {
1043 			if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------> serverInfo [%s]\n",serverInfo.c_str());
1044 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1045 
1046 			std::vector<std::string> serverList;
1047 			Tokenize(serverInfo,serverList,"\n");
1048 			for(int i = 0; i < (int)serverList.size(); i++) {
1049 				string &server = serverList[i];
1050 				if(trim(server) == "") {
1051 					continue;
1052 				}
1053 				std::vector<std::string> serverEntities;
1054 				Tokenize(server,serverEntities,"|");
1055 				const int MIN_FIELDS_EXPECTED = 14;
1056 
1057 				if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------> server [%s] serverEntities.size() = " MG_SIZE_T_SPECIFIER " MIN_FIELDS_EXPECTED = %d\n",server.c_str(),serverEntities.size(),MIN_FIELDS_EXPECTED);
1058 
1059 				if((int)serverEntities.size() >= MIN_FIELDS_EXPECTED) {
1060 					labelTitle.setText(lang.getString("AvailableServers"));
1061 
1062 					if(Config::getInstance().getString("Masterserver","") == "") {
1063 						labelTitle.setText("*** " + lang.getString("AvailableServers"));
1064 					}
1065 
1066 					MasterServerInfo *masterServerInfo=new MasterServerInfo();
1067 
1068 					//general info:
1069 					masterServerInfo->setGlestVersion(serverEntities[0]);
1070 					masterServerInfo->setPlatform(serverEntities[1]);
1071 					masterServerInfo->setBinaryCompileDate(serverEntities[2]);
1072 
1073 					//game info:
1074 					masterServerInfo->setServerTitle(serverEntities[3]);
1075 					masterServerInfo->setIpAddress(serverEntities[4]);
1076 
1077 					//game setup info:
1078 					masterServerInfo->setTech(serverEntities[5]);
1079 					masterServerInfo->setMap(serverEntities[6]);
1080 					masterServerInfo->setTileset(serverEntities[7]);
1081 					masterServerInfo->setActiveSlots(strToInt(serverEntities[8]));
1082 					masterServerInfo->setNetworkSlots(strToInt(serverEntities[9]));
1083 					masterServerInfo->setConnectedClients(strToInt(serverEntities[10]));
1084 					masterServerInfo->setExternalConnectPort(strToInt(serverEntities[11]));
1085 					masterServerInfo->setCountry(serverEntities[12]);
1086 					masterServerInfo->setStatus(strToInt(serverEntities[13]));
1087 
1088 					//printf("--------------> Country [%s] Status [%d]\n",masterServerInfo->getCountry().c_str(),masterServerInfo->getStatus());
1089 
1090 					//printf("Getting Ping time for host %s\n",masterServerInfo->getIpAddress().c_str());
1091 					//float pingTime = Socket::getAveragePingMS(masterServerInfo->getIpAddress().c_str(),1);
1092 					//printf("Ping time = %f\n",pingTime);
1093 					char szBuf[8096]="";
1094 					snprintf(szBuf,8096,"%s",masterServerInfo->getServerTitle().c_str());
1095 					masterServerInfo->setServerTitle(szBuf);
1096 
1097 					if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1098 
1099 					serverLines.push_back(new ServerLine( masterServerInfo, i, serverLinesYBase, serverLinesLineHeight, containerName));
1100 					delete masterServerInfo;
1101 				}
1102 				else {
1103 					if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1104 
1105 					Lang &lang= Lang::getInstance();
1106 					labelTitle.setText("*** " + lang.getString("AvailableServers") + "[" + intToStr(serverEntities.size()) + "][" + intToStr(MIN_FIELDS_EXPECTED) + "] [" + serverInfo + "]");
1107 
1108 					if(masterserverParseErrorShown == false) {
1109 						masterserverParseErrorShown = true;
1110 						SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line %d] error, no masterserver defined!\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1111 					}
1112 				}
1113 
1114 				if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1115 			}
1116 
1117 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1118 		}
1119 
1120     }
1121 	catch(const exception &ex) {
1122 	    labelTitle.setText("*** " + lang.getString("AvailableServers") + " [" + ex.what() + "]");
1123 	    SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line %d] error during Internet game status update: [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
1124 	}
1125 
1126 	if((int)serverLines.size() > numberOfOldServerLines) {
1127 		playServerFoundSound = true;
1128 	}
1129 }
1130 
1131 
connectToServer(string ipString,int port)1132 bool MenuStateMasterserver::connectToServer(string ipString, int port) {
1133 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START  ipString='%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,ipString.c_str());
1134 
1135 	ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
1136 	//Config& config= Config::getInstance();
1137 	Ip serverIp(ipString);
1138 
1139 	//int serverPort = Config::getInstance().getInt("PortServer",intToStr(GameConstants::serverPort).c_str());
1140 	int serverPort = port;
1141 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] try to connect to [%s] serverPort = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,serverIp.getString().c_str(),serverPort);
1142 	clientInterface->connect(serverIp, serverPort);
1143 	if(clientInterface->isConnected() == false) {
1144 		NetworkManager::getInstance().end();
1145 		NetworkManager::getInstance().init(nrClient);
1146 
1147 		mainMessageBoxState=1;
1148 		Lang &lang= Lang::getInstance();
1149 		showMessageBox(lang.getString("CouldNotConnect"), lang.getString("ConnectionFailed"), false);
1150 		return false;
1151 
1152 		//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] connection failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
1153 	}
1154 	else {
1155 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] connected to [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,serverIp.getString().c_str());
1156 
1157 		//save server ip
1158 		//config.setString("ServerIp", serverIp.getString());
1159 		//config.save();
1160 
1161 		for(time_t elapsedWait = time(NULL);
1162 			clientInterface->getIntroDone() == false &&
1163 			clientInterface->isConnected() &&
1164 			difftime(time(NULL),elapsedWait) <= 8;) {
1165 			if(clientInterface->isConnected()) {
1166 				//update lobby
1167 				clientInterface->updateLobby();
1168 				sleep(0);
1169 				//this->render();
1170 			}
1171 		}
1172 		if( clientInterface->isConnected() == true &&
1173 			clientInterface->getIntroDone() == true) {
1174 			return true;
1175 		}
1176 
1177 		return false;
1178 	}
1179 }
1180 
showMessageBox(const string & text,const string & header,bool toggle)1181 void MenuStateMasterserver::showMessageBox(const string &text, const string &header, bool toggle){
1182 	if(!toggle){
1183 		mainMessageBox.setEnabled(false);
1184 	}
1185 
1186 	if(!mainMessageBox.getEnabled()){
1187 		mainMessageBox.setText(text);
1188 		mainMessageBox.setHeader(header);
1189 		mainMessageBox.setEnabled(true);
1190 	}
1191 	else{
1192 		mainMessageBox.setEnabled(false);
1193 	}
1194 }
1195 
1196 
textInput(std::string text)1197 bool MenuStateMasterserver::textInput(std::string text) {
1198 	if (ircClient != NULL && ircClient->isConnected() == true
1199 			&& ircClient->getHasJoinedChannel() == true) {
1200 		return chatManager.textInput(text);
1201 	}
1202     return false;
1203 }
1204 
keyDown(SDL_KeyboardEvent key)1205 void MenuStateMasterserver::keyDown(SDL_KeyboardEvent key) {
1206 	//printf("In [%s::%s Line: %d] key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key.keysym.sym);
1207 
1208 	Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
1209 
1210 	if (ircClient != NULL && ircClient->isConnected() == true
1211 			&& ircClient->getHasJoinedChannel() == true) {
1212 		//chatmanger only if connected to irc!
1213 		if (chatManager.getEditEnabled() == true) {
1214 			//printf("keyDown key [%d] chatManager.getText() [%s]\n",key,chatManager.getText().c_str());
1215 			MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
1216 			//if (key == vkReturn && ircClient != NULL) {
1217 			if(isKeyPressed(SDLK_RETURN,key,false) == true && ircClient != NULL) {
1218 				ircClient->SendIRCCmdMessage(IRC_CHANNEL, chatManager.getText());
1219 			}
1220 		}
1221 		chatManager.keyDown(key);
1222 	}
1223     if(chatManager.getEditEnabled() == false) {
1224         //if(key == configKeys.getCharKey("ToggleMusic")) {
1225     	if(isKeyPressed(configKeys.getSDLKey("ToggleMusic"),key) == true) {
1226             Config &config = Config::getInstance();
1227             Lang &lang= Lang::getInstance();
1228 
1229             float configVolume = (config.getInt("SoundVolumeMusic") / 100.f);
1230             float currentVolume = CoreData::getInstance().getMenuMusic()->getVolume();
1231             if(currentVolume > 0) {
1232                 CoreData::getInstance().getMenuMusic()->setVolume(0.f);
1233                 consoleIRC.addLine(lang.getString("GameMusic") + " " + lang.getString("Off"));
1234             }
1235             else {
1236                 CoreData::getInstance().getMenuMusic()->setVolume(configVolume);
1237                 //If the config says zero, use the default music volume
1238                 //gameMusic->setVolume(configVolume ? configVolume : 0.9);
1239                 consoleIRC.addLine(lang.getString("GameMusic"));
1240             }
1241         }
1242         //else if(key == configKeys.getCharKey("SaveGUILayout")) {
1243     	else if(isKeyPressed(configKeys.getSDLKey("SaveGUILayout"),key) == true) {
1244             bool saved = GraphicComponent::saveAllCustomProperties(containerName);
1245             Lang &lang= Lang::getInstance();
1246             consoleIRC.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]");
1247         }
1248     }
1249 }
1250 
1251 }}//end namespace
1252