1 #include "pch.h"
2 #include "common/Def_Str.h"
3 #include "common/GuiCom.h"
4 #include "CGame.h"
5 #include "CGui.h"
6 #include "../vdrift/settings.h"
7 #include "../vdrift/game.h"
8 #include "../network/masterclient.hpp"
9 #include "../network/gameclient.hpp"
10 #include "common/MultiList2.h"
11 #include "common/Gui_Popup.h"
12 #include "common/MessageBox/MessageBox.h"
13 #include <boost/algorithm/string.hpp>
14 using namespace std;
15 using namespace MyGUI;
16
17
18 /// Gui Events
19
20 // [Multiplayer]
21 //---------------------------------------------------------------------
22
23 namespace
24 {
YesNo(bool cond)25 UString YesNo(bool cond)
26 {
27 return cond ? TR("#{Yes}") : TR("#{No}");
28 }
29
MsgError(const UString & what,const UString & title=TR ("#{Error}"))30 void inline MsgError(const UString& what, const UString& title = TR("#{Error}"))
31 {
32 Message::createMessageBox("Message", title, what, MessageBoxStyle::IconError | MessageBoxStyle::Ok);
33 }
34 }
35
36
rebuildGameList()37 void CGui::rebuildGameList()
38 {
39 if (!listServers || !app->mMasterClient) return;
40 Mli li = listServers;
41 li->removeAllItems();
42
43 protocol::GameList list = app->mMasterClient->getList();
44 const static char* sBoost[4] = {"#{Never}","#{FuelLap}","#{FuelTime}","#{Always}"};
45
46 for (protocol::GameList::const_iterator it = list.begin(); it != list.end(); ++it)
47 {
48 li->addItem("#C0FFC0"+UString(it->second.name)); int l = li->getItemCount()-1;
49 li->setSubItemNameAt(1,l, "#50FF50"+ string(it->second.track));
50 li->setSubItemNameAt(2,l, "#80FFC0"+ toStr((int)it->second.laps));
51 li->setSubItemNameAt(3,l, "#FFFF00"+ toStr((int)it->second.players));
52 li->setSubItemNameAt(4,l, "#80FFFF"+ YesNo((bool)it->second.collisions));
53 li->setSubItemNameAt(5,l, "#D0D0FF"+ string(it->second.sim_mode));
54 li->setSubItemNameAt(6,l, "#A0D0FF"+ TR(sBoost[it->second.boost_type]));
55 li->setSubItemNameAt(iColLock,l, "#FF6060"+ YesNo((bool)it->second.locked));
56 li->setSubItemNameAt(iColHost,l, "#FF9000"+ net::IPv4(it->second.address));
57 li->setSubItemNameAt(iColPort,l, "#FFB000"+ toStr((int)it->second.port));
58 }
59 }
60
rebuildPlayerList()61 void CGui::rebuildPlayerList()
62 {
63 if (!listPlayers || !app->mClient) return;
64 Mli li = listPlayers;
65 li->removeAllItems();
66
67 // Add self
68 int peerCount = app->mClient->getPeerCount();
69 li->addItem("#C0E0FF"+ pSet->nickname);
70 li->setSubItemNameAt(1,0, "#80FFFF"+ sListCar);
71 li->setSubItemNameAt(2,0, "#F0F060"+ toStr(peerCount));
72 li->setSubItemNameAt(3,0, "#C0F0F0" "0"); bool rd = app->mClient->isReady();
73 li->setSubItemNameAt(4,0, (rd?"#60FF60":"#FF8080")+ YesNo(rd));
74
75 // Add others
76 bool allReady = true;
77 const PeerMap peers = app->mClient->getPeers();
78 for (PeerMap::const_iterator it = peers.begin(); it != peers.end(); ++it)
79 {
80 if (it->second.name.empty() || it->second.connection == PeerInfo::DISCONNECTED)
81 continue;
82 // Determine if everyone is ready and connected
83 if (it->second.peers != peerCount || !it->second.ready)
84 allReady = false;
85
86 // Add list item
87 li->addItem("#C0E0FF"+ it->second.name); int l = li->getItemCount()-1;
88 li->setSubItemNameAt(1,l, "#80FFFF"+ it->second.car);
89 li->setSubItemNameAt(2,l, "#F0F060"+ toStr(it->second.peers));
90 //static int pp=0; pp+=50; int p = (pp)%600; //test clr
91 int p = it->second.ping;
92 li->setSubItemNameAt(3,l, CGuiCom::clrsDiff[std::min(7,1+p/100)]+ toStr(p));
93 bool rd = it->second.ready;
94 li->setSubItemNameAt(4,l, (rd?"#60FF60":"#FF8080")+ YesNo(rd));
95 }
96 // Allow host to start the game
97 if (app->mLobbyState == HOSTING)
98 btnNetReady->setEnabled(allReady);
99 }
100
updateGameInfo()101 void CGui::updateGameInfo()
102 {
103 // set game config
104 if (netGameInfo.name && edNetGameName)
105 { string name(netGameInfo.name);
106 edNetGameName->setCaption(name);
107 }
108 if (netGameInfo.track)
109 { string track(netGameInfo.track);
110 gcom->sListTrack = track;
111 gcom->bListTrackU = netGameInfo.track[31]==1; //user
112 gcom->ReadTrkStats();
113 }
114 updateGameSet();
115 updateGameInfoGUI();
116 }
117
118 /// update game info
updateGameInfoGUI()119 void CGui::updateGameInfoGUI()
120 {
121 if (!valNetGameInfo) return;
122 using Ogre::String;
123
124 String s; const protocol::GameInfo& g = netGameInfo;
125 s += TR("#40FF40#{Track}: ") + gcom->sListTrack +"\n";
126 s += TR("#60A060#{Reverse}: ") + YesNo(g.reversed) +"\n";
127 s += "\n";
128 s += TR("#80F0F0#{Laps}: ") + toStr(g.laps) +"\n";
129 s += TR("#409090#{ReverseStartOrder}: ") + YesNo(g.start_order) +"\n";
130 s += TR("#F0F040#{Players}: ") + toStr(g.players) +"\n";
131 s += "\n";
132 s += TR("#D090E0#{Game}") +"\n";
133 s += TR("#90B0E0 #{Simulation}: ") + String(g.sim_mode) +"\n";
134 s += TR("#A0D0D0 #{CarCollis}: ") + YesNo(g.collisions) +"\n";
135 s += "\n";
136 #define cmbs(cmb, i) (i>=0 && i < cmb->getItemCount() ? cmb->getItemNameAt(i) : TR("#{Any}"))
137 s += TR("#80C0FF #{Boost}: ") + "#90D0FF"+ cmbs(cmbBoost, g.boost_type) +"\n";
138 s += TR("#6098A0 #{Flip}: ") + "#7098A0"+ cmbs(cmbFlip, g.flip_type) +"\n";
139 s += "\n";
140 s += TR("#A090E0 #{Damage}: ") + "#B090FF"+ cmbs(cmbDamage, g.damage_type) +"\n";
141 s += TR("#A090C0 #{DamageDecLap}: ") + "#B0A0F0"+ fToStr(g.damage_lap_dec,0,3) +" %\n\n";
142 s += TR("#B080C0 #{InputMapRewind}: ") + "#C090D0"+ cmbs(cmbRewind, g.rewind_type) +"\n";
143 //float boost_power;
144 //float boost_lap_inc, rewind_lap_inc; //todo
145 //uint8_t tree_collis; float tree_mult;
146
147 valNetGameInfo->setCaption(s);
148 }
149
150
151 /// Receive set game from host
152 //---------------------------------------------------------------------
updateGameSet()153 void CGui::updateGameSet()
154 {
155 pSet->game.sim_mode = netGameInfo.sim_mode; LogO("== Netw sim mode: " + pSet->game.sim_mode);
156
157 pSet->game.collis_cars = netGameInfo.collisions>0;
158 pSet->game.num_laps = netGameInfo.laps; LogO("== Netw laps num: " + toStr(pSet->game.num_laps));
159 pSet->game.trackreverse = netGameInfo.reversed>0;
160
161 pSet->game.start_order = netGameInfo.start_order;
162 pSet->game.collis_veget = netGameInfo.tree_collis>0;
163 pSet->game.trees = netGameInfo.tree_mult;
164
165 pSet->game.BoostDefault(); //
166 pSet->game.boost_type = netGameInfo.boost_type;
167 pSet->game.boost_power = netGameInfo.boost_power;
168 pSet->game.flip_type = netGameInfo.flip_type;
169
170 pSet->game.damage_type = netGameInfo.damage_type;
171 pSet->game.damage_dec = netGameInfo.damage_lap_dec;
172 pSet->game.rewind_type = netGameInfo.rewind_type;
173 //boost_lap_inc, rewind_lap_inc; //todo
174 }
175
176 /// Send upload to peers
177 //---------------------------------------------------------------------
uploadGameInfo()178 void CGui::uploadGameInfo()
179 {
180 if (!app->mMasterClient || !app->mClient || !edNetGameName || !pSet)
181 return;
182 protocol::GameInfo game;
183 string sGame = edNetGameName->getCaption();
184 string sTrack = gcom->sListTrack, sSim = pSet->gui.sim_mode;
185
186 memset(game.name, 0, sizeof(game.name));
187 memset(game.track, 0, sizeof(game.track));
188 memset(game.sim_mode, 0, sizeof(game.sim_mode));
189 strcpy(game.name, sGame.c_str());
190 strcpy(game.track, sTrack.c_str()); game.track[31] = gcom->bListTrackU ? 1:0; //user
191 strcpy(game.sim_mode, sSim.c_str());
192 game.players = app->mClient->getPeerCount()+1;
193
194 game.collisions = pSet->gui.collis_cars?1:0;
195 game.laps = pSet->gui.num_laps; LogO("== Netw laps num: " + toStr(pSet->gui.num_laps));
196 game.reversed = pSet->gui.trackreverse?1:0;
197
198 game.start_order = pSet->gui.start_order;
199 game.tree_collis = pSet->gui.collis_veget?1:0;
200 game.tree_mult = pSet->gui.trees;
201
202 game.boost_type = pSet->gui.boost_type;
203 game.boost_power = pSet->gui.boost_power;
204 game.flip_type = pSet->gui.flip_type;
205
206 game.damage_type = pSet->gui.damage_type;
207 game.damage_lap_dec = pSet->gui.damage_dec;
208 game.rewind_type = pSet->gui.rewind_type;
209 //boost_lap_inc, rewind_lap_inc; //todo
210
211 game.port = pSet->local_port;
212 game.locked = !edNetPassword->getCaption().empty();
213 {
214 //? boost::mutex::scoped_lock lock(netGuiMutex);
215 netGameInfo = game; // for host gui info
216 }
217 app->mMasterClient->updateGame(game); // Upload to master server
218 if (app->mClient) // Send to peers
219 app->mClient->broadcastGameInfo(game);
220 }
221 //---------------------------------------------------------------------
222
223
setNetGuiHosting(bool enabled)224 void CGui::setNetGuiHosting(bool enabled)
225 {
226 edNetGameName->setEnabled(enabled);
227 edNetPassword->setEnabled(enabled);
228 edNetPassword->setVisible(enabled);
229 valNetPassword->setVisible(enabled);
230 btnNetReady->setEnabled(!enabled);
231 btnNetReady->setCaption(enabled ? TR("#{NetStart}") : TR("#{NetReady}"));
232 }
233
gameListChanged(protocol::GameList list)234 void CGui::gameListChanged(protocol::GameList list)
235 {
236 (void)list;
237 boost::mutex::scoped_lock lock(netGuiMutex);
238 bRebuildGameList = true;
239 }
240
241 // add new msg at end
AddChatMsg(const MyGUI::UString & clr,const MyGUI::UString & msg,bool add)242 void CGui::AddChatMsg(const MyGUI::UString& clr, const MyGUI::UString& msg, bool add)
243 {
244 if (!app->isFocGui) // if not in gui, show on hud
245 { sChatLast1 = sChatLast2;
246 sChatLast2 = msg;
247 iChatMove = 0;
248 }
249 sChatBuffer = add ? (sChatBuffer + clr + msg + "\n") : (clr + msg + "\n");
250 bUpdChat = true;
251 }
252
peerConnected(PeerInfo peer)253 void CGui::peerConnected(PeerInfo peer)
254 {
255 // Master server player count update
256 if (app->mLobbyState == HOSTING) uploadGameInfo();
257 // Schedule Gui updates
258 boost::mutex::scoped_lock lock(netGuiMutex);
259 AddChatMsg("#00FF00", TR("#{Connected}: ") + peer.name);
260 bRebuildPlayerList = true;
261 }
262
peerDisconnected(PeerInfo peer)263 void CGui::peerDisconnected(PeerInfo peer)
264 {
265 if (peer.name.empty()) return;
266 // Master server player count update
267 if (app->mLobbyState == HOSTING) uploadGameInfo();
268 // Schedule Gui updates
269 boost::mutex::scoped_lock lock(netGuiMutex);
270 AddChatMsg("#FF8000", TR("#{Disconnected}: ") + peer.name);
271 bRebuildPlayerList = true;
272 }
273
peerInfo(PeerInfo peer)274 void CGui::peerInfo(PeerInfo peer)
275 {
276 (void)peer;
277 boost::mutex::scoped_lock lock(netGuiMutex);
278 bRebuildPlayerList = true;
279 }
280
peerMessage(PeerInfo peer,string msg)281 void CGui::peerMessage(PeerInfo peer, string msg)
282 {
283 boost::mutex::scoped_lock lock(netGuiMutex);
284
285 int len = peer.name.length();
286 if (len == 0) return;
287
288 int hc = 16; // color from name
289 hc += len; hc += peer.name[0];
290 if (len > 3) hc += peer.name[2];
291
292 const static int num = 24;
293 const static char sclr[num][8] = {
294 "#80FFC0","#C0FFC0","#B0FF40","#80C060",
295 "#90E0E0","#40FFFF","#F0F0C0","#E0E040",
296 "#FFC0FF","#FF80C0","#FFC040","#FF8080",
297 "#FF4080","#FFA050","#FF8020","#C0C0C0",
298 "#50B0E0","#C080FF","#C0C0FF","#8080FF",
299 "#4080FF","#80C0FF","#E0F0FF","#F0F0F0"};
300 /*for (int i=0; i<num; ++i) //test clrs
301 AddChatMsg(sclr[i], UString(peer.name) + ": " + msg);/**/
302
303 AddChatMsg(sclr[hc % num], UString(peer.name) + ": " + msg);
304 bRebuildPlayerList = true; // For ping updates in the list
305 }
306
peerState(PeerInfo peer,uint8_t state)307 void CGui::peerState(PeerInfo peer, uint8_t state)
308 {
309 (void)peer;
310 boost::mutex::scoped_lock lock(netGuiMutex);
311 if (state == protocol::START_GAME)
312 {
313 bStartGame = true;
314 bStartedGame = true;
315 }
316 }
317
gameInfo(protocol::GameInfo game)318 void CGui::gameInfo(protocol::GameInfo game)
319 {
320 boost::mutex::scoped_lock lock(netGuiMutex);
321 netGameInfo = game;
322 bUpdateGameInfo = true;
323 }
324
returnToLobby()325 void CGui::returnToLobby()
326 {
327 btnNetReady->setCaption(TR("#{NetReady}"));
328 app->isFocGui = true; // show back gui
329 toggleGui(false);
330 }
331
startRace()332 void CGui::startRace()
333 {
334 LogO("== Netw startRace +");
335 pGame->timer.waiting = false;
336 pGame->timer.end_sim = false;
337 }
338
339 /// Lap time got from network
timeInfo(ClientID id,uint8_t lap,double time)340 void CGui::timeInfo(ClientID id, uint8_t lap, double time)
341 {
342 //if (!ap->mClient) return;
343 if (id == 0) id = app->mClient->getId();
344 int n = pGame->timer.netw_lap;
345
346 LogO("== Netw Lap " +toStr(lap) + "==" + toStr(n) + (lap == n ? "Good":"BAD!") +
347 " finished by " +toStr(id) + " time:"+ toStr(float(time)));
348 if (id >= app->carModels.size() || id < 0)
349 { LogO("== Netw Lap id wrong !" ); return; }
350
351 //pGame->timer.Lap(id, 0,0, true, pSet->game.trackreverse/*<, pSet->boost_type*/);
352 if (pGame->timer.LapNetworkTime(id, lap, time)) // is the same as above but sets client's time
353 {}//LogO("== Netw Lap OK");
354
355 //carModels[id]->trackPercent = 0.f;
356 //carPoses[id].percent = 0.f;
357 }
358
error(string what)359 void CGui::error(string what)
360 {
361 boost::mutex::scoped_lock lock(netGuiMutex);
362 AddChatMsg("#FF3030", TR("#{Error}! ") + what);
363 }
364
join(string host,string port,string password)365 void CGui::join(string host, string port, string password)
366 {
367 try
368 { app->mClient.reset(new P2PGameClient(this, pSet->local_port));
369 app->mClient->updatePlayerInfo(pSet->nickname, sListCar);
370 app->mClient->connect(host, boost::lexical_cast<int>(port), password); // Lobby phase started automatically
371 boost::mutex::scoped_lock lock(netGuiMutex);
372 AddChatMsg("#00FFFF", TR("#{ConnectingTo} ") + host + ":" + port, false); // clears chat
373 }catch (...)
374 { MsgError(TR("#{NewtworkFailed}"), TR("NetworkError"));
375 return;
376 }
377
378 updateGameInfoGUI();
379 rebuildPlayerList();
380 setNetGuiHosting(false);
381
382 tabsNet->setIndexSelected(1);
383 panNetServer->setVisible(true); panNetGame->setVisible(false);
384 panNetTrack->setVisible(true); gcom->trkList->setVisible(false);
385 }
386
evBtnNetRefresh(WP)387 void CGui::evBtnNetRefresh(WP)
388 {
389 app->mMasterClient.reset(new MasterClient(this));
390 app->mMasterClient->connect(pSet->master_server_address, pSet->master_server_port);
391 // The actual refresh will be requested automatically when the connection is made
392 }
393
evBtnNetJoin(WP)394 void CGui::evBtnNetJoin(WP)
395 {
396 // join selected game
397 if (!listServers || !pSet) return;
398 size_t i = listServers->getIndexSelected();
399 if (i == ITEM_NONE) return;
400
401 // TODO: Comparing against localized string is EVIL!
402 if (listServers->getSubItemNameAt(iColLock, i).substr(7) == TR("#{No}"))
403 {
404 string host = listServers->getSubItemNameAt(iColHost, i).substr(7);
405 string port = listServers->getSubItemNameAt(iColPort, i).substr(7);
406
407 join(host, port, "");
408 }else
409 popup->Show(newDelegate(this, &CGui::evBtnNetJoinLockedClose),
410 TR("#{NetJoinLocked}"), true,
411 TR("#{NetPassword}"), "", "", "",
412 "", "", "","",
413 TR("#{MessageBox_Ok}"), TR("#{MessageBox_Cancel}"), "", "");
414 }
415
evBtnNetJoinLockedClose()416 void CGui::evBtnNetJoinLockedClose()
417 {
418 popup->Hide();
419 if (popup->btnResult != 0 || !listServers || !pSet) return;
420 size_t i = listServers->getIndexSelected(); if (i == ITEM_NONE) return;
421
422 string host = listServers->getSubItemNameAt(iColHost, i).substr(7);
423 string port = listServers->getSubItemNameAt(iColPort, i).substr(7);
424
425 join(host, port, popup->edit0); // host, port, password
426 }
427
evBtnNetCreate(WP)428 void CGui::evBtnNetCreate(WP)
429 {
430 // create game ..
431 if (app->mLobbyState == DISCONNECTED)
432 { try
433 {
434 app->mClient.reset(new P2PGameClient(this, pSet->local_port));
435 app->mClient->updatePlayerInfo(pSet->nickname, sListCar);
436 app->mClient->startLobby();
437 }
438 catch (...)
439 { MsgError(TR("#{NewtworkFailed}"), TR("NetworkError"));
440 return;
441 }
442 app->mLobbyState = HOSTING;
443 if (!app->mMasterClient)
444 {
445 app->mMasterClient.reset(new MasterClient(this));
446 app->mMasterClient->connect(pSet->master_server_address, pSet->master_server_port);
447 }
448 uploadGameInfo();
449 updateGameInfoGUI();
450
451 rebuildPlayerList();
452 setNetGuiHosting(true);
453
454 tabsNet->setIndexSelected(1);
455 panNetServer->setVisible(true); panNetGame->setVisible(false);
456 panNetTrack->setVisible(false); gcom->trkList->setVisible(true);
457
458 boost::mutex::scoped_lock lock(netGuiMutex);
459 AddChatMsg("#00FFC0", TR("#{ListeningOnPort} ") + toStr(pSet->local_port) + "...", false); //clears chat
460 }
461 }
462
evBtnNetLeave(WP)463 void CGui::evBtnNetLeave(WP)
464 {
465 // leave current game
466 app->mLobbyState = DISCONNECTED;
467 app->mClient.reset();
468 app->mMasterClient.reset();
469 setNetGuiHosting(false);
470
471 tabsNet->setIndexSelected(0);
472 panNetServer->setVisible(false); panNetGame->setVisible(true);
473 panNetTrack->setVisible(false); gcom->trkList->setVisible(true);
474 }
475
evBtnNetDirect(WP)476 void CGui::evBtnNetDirect(WP)
477 {
478 popup->Show(newDelegate(this, &CGui::evBtnNetDirectClose),
479 TR("#{NetDirectConnect}"), true,
480 TR("#{NetAddress}"), TR("#{NetPort}"), TR("#{NetPassword}"), "",
481 "localhost", toStr(protocol::DEFAULT_PORT), "","",
482 TR("#{MessageBox_Ok}"), TR("#{MessageBox_Cancel}"), "", "");
483 }
484
evBtnNetDirectClose()485 void CGui::evBtnNetDirectClose()
486 {
487 popup->Hide();
488 if (popup->btnResult != 0) return;
489
490 join(popup->edit0, popup->edit1, popup->edit2); // host, port, password
491 }
492
evBtnNetReady(WP)493 void CGui::evBtnNetReady(WP)
494 {
495 if (!app->mClient) return;
496
497 app->mClient->toggleReady();
498 if (app->mLobbyState == HOSTING)
499 {
500 LogO("== Netw Ready, hosting...");
501 if (!bStartedGame)
502 {
503 if (app->mMasterClient) app->mMasterClient->signalStart();
504 boost::mutex::scoped_lock lock(netGuiMutex);
505 bStartGame = true;
506 bStartedGame = true;
507 btnNetReady->setCaption( TR("#{NetNew}") );
508 }else{
509 app->mClient->returnToLobby();
510 boost::mutex::scoped_lock lock(netGuiMutex);
511 bStartGame = false;
512 bStartedGame = false;
513 btnNetReady->setCaption( TR("#{NetStart}") );
514 }
515 }else
516 {
517 if (app->mClient->isReady())
518 btnNetReady->setCaption( TR("#{NetWaiting}") );
519 else btnNetReady->setCaption( TR("#{NetReady}") );
520 }
521
522 rebuildPlayerList();
523 }
524
525
chatSendMsg()526 void CGui::chatSendMsg()
527 {
528 if (!app->mClient || !edNetChatMsg) return;
529 if (edNetChatMsg->getCaption().empty()) return;
530
531 app->mClient->sendMessage(edNetChatMsg->getCaption());
532 edNetChatMsg->setCaption("");
533 }
534
evEdNetGameName(EditPtr ed)535 void CGui::evEdNetGameName(EditPtr ed)
536 {
537 // game name text changed
538 pSet->netGameName = ed->getCaption();
539 if (app->mLobbyState != HOSTING || !app->mMasterClient || !app->mClient) return;
540 uploadGameInfo();
541 }
542
evEdNetPassword(EditPtr)543 void CGui::evEdNetPassword(EditPtr)
544 {
545 // password changed
546 if (app->mLobbyState != HOSTING || !app->mMasterClient || !app->mClient) return;
547
548 app->mClient->setPassword(edNetPassword->getCaption());
549 uploadGameInfo();
550 }
551
552 // net settings
553
evEdNetNick(EditPtr ed)554 void CGui::evEdNetNick(EditPtr ed)
555 {
556 pSet->nickname = ed->getCaption();
557 if (app->mClient) app->mClient->updatePlayerInfo(pSet->nickname, sListCar);
558 }
559
evEdNetServerIP(EditPtr ed)560 void CGui::evEdNetServerIP(EditPtr ed)
561 {
562 pSet->master_server_address = ed->getCaption();
563 }
564
evEdNetServerPort(EditPtr ed)565 void CGui::evEdNetServerPort(EditPtr ed)
566 {
567 pSet->master_server_port = s2i(ed->getCaption());
568 }
569
evEdNetLocalPort(EditPtr ed)570 void CGui::evEdNetLocalPort(EditPtr ed)
571 {
572 pSet->local_port = s2i(ed->getCaption());
573 }
574
575
576 /// Gui updates from networking
577 // handled in ogre thread as MyGUI is not thread-safe
UpdGuiNetw()578 void CGui::UpdGuiNetw()
579 {
580 if (app->isFocGui)
581 {
582 if (app->mMasterClient) {
583 std::string error = app->mMasterClient->getError();
584 if (!error.empty())
585 Message::createMessageBox("Message", TR("#{Error}"), error,
586 MessageBoxStyle::IconError | MessageBoxStyle::Ok);
587 }
588 boost::mutex::scoped_lock lock(netGuiMutex);
589 if (bRebuildGameList) {
590 bRebuildGameList = false; rebuildGameList(); }
591 if (bRebuildPlayerList) {
592 bRebuildPlayerList = false; rebuildPlayerList(); }
593 if (bUpdateGameInfo) {
594 bUpdateGameInfo = false; updateGameInfo(); }
595 if (bUpdChat) {
596 bUpdChat = false; edNetChat->setCaption(sChatBuffer); }
597 if (bStartGame) {
598 bStartGame = false; app->mClient->startGame(); btnNewGameStart(NULL); }
599 }
600 }
601