Merge lp:~widelands-dev/widelands/fix_asan_crash_nethost into lp:widelands

Proposed by SirVer
Status: Merged
Merged at revision: 8507
Proposed branch: lp:~widelands-dev/widelands/fix_asan_crash_nethost
Merge into: lp:widelands
Diff against target: 950 lines (+255/-249)
3 files modified
src/network/gamehost.cc (+211/-208)
src/wui/multiplayersetupgroup.cc (+43/-40)
src/wui/multiplayersetupgroup.h (+1/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/fix_asan_crash_nethost
Reviewer Review Type Date Requested Status
GunChleoc Approve
Review via email: mp+334288@code.launchpad.net

Commit message

Renamed some variables and fixed an ASAN reported crash.

The bug was that in MultiPlayerPlayerGroup, settings_->settings().players[id] was used. This vector always has the length of the players in the map. But id runs from 0 to MAX_PLAYERS - 1. The fix was simply to check that id < players.size().

To post a comment you must log in.
Revision history for this message
GunChleoc (gunchleoc) wrote :

LGTM :)

Those index shifts were a major pain in the butt too when I implemented that.

@bunnybot merge

review: Approve
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 2863. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/307774210.
Appveyor build 2672. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_fix_asan_crash_nethost-2672.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/network/gamehost.cc'
--- src/network/gamehost.cc 2017-11-14 08:15:48 +0000
+++ src/network/gamehost.cc 2017-11-27 07:16:30 +0000
@@ -587,9 +587,9 @@
587 disconnect_client(i, "GAME_STARTED_AT_CONNECT");587 disconnect_client(i, "GAME_STARTED_AT_CONNECT");
588 }588 }
589589
590 SendPacket s;590 SendPacket packet;
591 s.unsigned_8(NETCMD_LAUNCH);591 packet.unsigned_8(NETCMD_LAUNCH);
592 broadcast(s);592 broadcast(packet);
593593
594 Widelands::Game game;594 Widelands::Game game;
595 game.set_ai_training_mode(g_options.pull_section("global").get_bool("ai_training", false));595 game.set_ai_training_mode(g_options.pull_section("global").get_bool("ai_training", false));
@@ -704,10 +704,10 @@
704 } else if (curtime - d->last_heartbeat >= SERVER_TIMESTAMP_INTERVAL) {704 } else if (curtime - d->last_heartbeat >= SERVER_TIMESTAMP_INTERVAL) {
705 d->last_heartbeat = curtime;705 d->last_heartbeat = curtime;
706706
707 SendPacket s;707 SendPacket packet;
708 s.unsigned_8(NETCMD_TIME);708 packet.unsigned_8(NETCMD_TIME);
709 s.signed_32(d->pseudo_networktime);709 packet.signed_32(d->pseudo_networktime);
710 broadcast(s);710 broadcast(packet);
711711
712 committed_network_time(d->pseudo_networktime);712 committed_network_time(d->pseudo_networktime);
713713
@@ -724,11 +724,11 @@
724void GameHost::send_player_command(Widelands::PlayerCommand& pc) {724void GameHost::send_player_command(Widelands::PlayerCommand& pc) {
725 pc.set_duetime(d->committed_networktime + 1);725 pc.set_duetime(d->committed_networktime + 1);
726726
727 SendPacket s;727 SendPacket packet;
728 s.unsigned_8(NETCMD_PLAYERCOMMAND);728 packet.unsigned_8(NETCMD_PLAYERCOMMAND);
729 s.signed_32(pc.duetime());729 packet.signed_32(pc.duetime());
730 pc.serialize(s);730 pc.serialize(packet);
731 broadcast(s);731 broadcast(packet);
732 d->game->enqueue_command(&pc);732 d->game->enqueue_command(&pc);
733733
734 committed_network_time(d->committed_networktime + 1);734 committed_network_time(d->committed_networktime + 1);
@@ -746,38 +746,38 @@
746 return;746 return;
747747
748 if (msg.recipient.empty()) {748 if (msg.recipient.empty()) {
749 SendPacket s;749 SendPacket packet;
750 s.unsigned_8(NETCMD_CHAT);750 packet.unsigned_8(NETCMD_CHAT);
751 s.signed_16(msg.playern);751 packet.signed_16(msg.playern);
752 s.string(msg.sender);752 packet.string(msg.sender);
753 s.string(msg.msg);753 packet.string(msg.msg);
754 s.unsigned_8(0);754 packet.unsigned_8(0);
755 broadcast(s);755 broadcast(packet);
756756
757 d->chat.receive(msg);757 d->chat.receive(msg);
758 } else { // personal messages758 } else { // personal messages
759 SendPacket s;759 SendPacket packet;
760 s.unsigned_8(NETCMD_CHAT);760 packet.unsigned_8(NETCMD_CHAT);
761761
762 // Is this a pm for the host player?762 // Is this a pm for the host player?
763 if (d->localplayername == msg.recipient) {763 if (d->localplayername == msg.recipient) {
764 d->chat.receive(msg);764 d->chat.receive(msg);
765 // Write the SendPacket - will be used below to show that the message765 // Write the SendPacket - will be used below to show that the message
766 // was received.766 // was received.
767 s.signed_16(msg.playern);767 packet.signed_16(msg.playern);
768 s.string(msg.sender);768 packet.string(msg.sender);
769 s.string(msg.msg);769 packet.string(msg.msg);
770 s.unsigned_8(1);770 packet.unsigned_8(1);
771 s.string(msg.recipient);771 packet.string(msg.recipient);
772 } else { // Find the recipient772 } else { // Find the recipient
773 int32_t clientnum = check_client(msg.recipient);773 int32_t clientnum = check_client(msg.recipient);
774 if (clientnum >= 0) {774 if (clientnum >= 0) {
775 s.signed_16(msg.playern);775 packet.signed_16(msg.playern);
776 s.string(msg.sender);776 packet.string(msg.sender);
777 s.string(msg.msg);777 packet.string(msg.msg);
778 s.unsigned_8(1);778 packet.unsigned_8(1);
779 s.string(msg.recipient);779 packet.string(msg.recipient);
780 d->net->send(d->clients.at(clientnum).sock_id, s);780 d->net->send(d->clients.at(clientnum).sock_id, packet);
781 log(781 log(
782 "[Host]: personal chat: from %s to %s\n", msg.sender.c_str(), msg.recipient.c_str());782 "[Host]: personal chat: from %s to %s\n", msg.sender.c_str(), msg.recipient.c_str());
783 } else {783 } else {
@@ -791,10 +791,10 @@
791 d->chat.receive(err);791 d->chat.receive(err);
792 return; // nothing left to do!792 return; // nothing left to do!
793 }793 }
794 s.signed_16(-2); // System message794 packet.signed_16(-2); // System message
795 s.string("");795 packet.string("");
796 s.string(fail);796 packet.string(fail);
797 s.unsigned_8(0);797 packet.unsigned_8(0);
798 }798 }
799 }799 }
800800
@@ -819,7 +819,7 @@
819 if (d->clients.at(j).usernum == static_cast<int16_t>(i))819 if (d->clients.at(j).usernum == static_cast<int16_t>(i))
820 break;820 break;
821 if (j < d->clients.size())821 if (j < d->clients.size())
822 d->net->send(d->clients.at(j).sock_id, s);822 d->net->send(d->clients.at(j).sock_id, packet);
823 else823 else
824 // Better no wexception it would break the whole game824 // Better no wexception it would break the whole game
825 log("WARNING: user was found but no client is connected to it!\n");825 log("WARNING: user was found but no client is connected to it!\n");
@@ -904,13 +904,13 @@
904 const std::string& b,904 const std::string& b,
905 const std::string& c) {905 const std::string& c) {
906 // First send to all clients906 // First send to all clients
907 SendPacket s;907 SendPacket packet;
908 s.unsigned_8(NETCMD_SYSTEM_MESSAGE_CODE);908 packet.unsigned_8(NETCMD_SYSTEM_MESSAGE_CODE);
909 s.string(code);909 packet.string(code);
910 s.string(a);910 packet.string(a);
911 s.string(b);911 packet.string(b);
912 s.string(c);912 packet.string(c);
913 broadcast(s);913 broadcast(packet);
914914
915 // Now add to our own chatbox915 // Now add to our own chatbox
916 ChatMessage msg(NetworkGamingMessages::get_message(code, a, b, c));916 ChatMessage msg(NetworkGamingMessages::get_message(code, a, b, c));
@@ -967,7 +967,7 @@
967967
968 std::vector<PlayerSettings>::size_type oldplayers = d->settings.players.size();968 std::vector<PlayerSettings>::size_type oldplayers = d->settings.players.size();
969969
970 SendPacket s;970 SendPacket packet;
971971
972 // Care about the host972 // Care about the host
973 if (static_cast<int32_t>(maxplayers) <= d->settings.playernum &&973 if (static_cast<int32_t>(maxplayers) <= d->settings.playernum &&
@@ -989,11 +989,11 @@
989 d->clients.at(j).playernum = UserSettings::none();989 d->clients.at(j).playernum = UserSettings::none();
990990
991 // Broadcast change991 // Broadcast change
992 s.reset();992 packet.reset();
993 s.unsigned_8(NETCMD_SETTING_USER);993 packet.unsigned_8(NETCMD_SETTING_USER);
994 s.unsigned_32(i);994 packet.unsigned_32(i);
995 write_setting_user(s, i);995 write_setting_user(packet, i);
996 broadcast(s);996 broadcast(packet);
997 }997 }
998 }998 }
999999
@@ -1016,16 +1016,16 @@
1016 }1016 }
10171017
1018 // Broadcast new map info1018 // Broadcast new map info
1019 s.reset();1019 packet.reset();
1020 s.unsigned_8(NETCMD_SETTING_MAP);1020 packet.unsigned_8(NETCMD_SETTING_MAP);
1021 write_setting_map(s);1021 write_setting_map(packet);
1022 broadcast(s);1022 broadcast(packet);
10231023
1024 // Broadcast new player settings1024 // Broadcast new player settings
1025 s.reset();1025 packet.reset();
1026 s.unsigned_8(NETCMD_SETTING_ALLPLAYERS);1026 packet.unsigned_8(NETCMD_SETTING_ALLPLAYERS);
1027 write_setting_all_players(s);1027 write_setting_all_players(packet);
1028 broadcast(s);1028 broadcast(packet);
10291029
1030 // If possible, offer the map / saved game as transfer1030 // If possible, offer the map / saved game as transfer
1031 // TODO(unknown): not yet able to handle directory type maps / savegames1031 // TODO(unknown): not yet able to handle directory type maps / savegames
@@ -1060,9 +1060,10 @@
1060 }1060 }
1061 }1061 }
10621062
1063 s.reset();1063 packet.reset();
1064 if (write_map_transfer_info(s, mapfilename))1064 if (write_map_transfer_info(packet, mapfilename)) {
1065 broadcast(s);1065 broadcast(packet);
1066 }
1066}1067}
10671068
1068void GameHost::set_player_state(uint8_t const number,1069void GameHost::set_player_state(uint8_t const number,
@@ -1138,18 +1139,18 @@
1138 player.name = get_computer_player_name(number);1139 player.name = get_computer_player_name(number);
11391140
1140 // Broadcast change to player1141 // Broadcast change to player
1141 SendPacket s;1142 SendPacket packet;
1142 s.reset();1143 packet.reset();
1143 s.unsigned_8(NETCMD_SETTING_PLAYER);1144 packet.unsigned_8(NETCMD_SETTING_PLAYER);
1144 s.unsigned_8(number);1145 packet.unsigned_8(number);
1145 write_setting_player(s, number);1146 write_setting_player(packet, number);
1146 broadcast(s);1147 broadcast(packet);
11471148
1148 // Let clients know whether their slot has changed1149 // Let clients know whether their slot has changed
1149 s.reset();1150 packet.reset();
1150 s.unsigned_8(NETCMD_SETTING_ALLUSERS);1151 packet.unsigned_8(NETCMD_SETTING_ALLUSERS);
1151 write_setting_all_users(s);1152 write_setting_all_users(packet);
1152 broadcast(s);1153 broadcast(packet);
1153}1154}
11541155
1155void GameHost::set_player_tribe(uint8_t const number,1156void GameHost::set_player_tribe(uint8_t const number,
@@ -1179,11 +1180,11 @@
1179 player.initialization_index = 0;1180 player.initialization_index = 0;
11801181
1181 // broadcast changes1182 // broadcast changes
1182 SendPacket s;1183 SendPacket packet;
1183 s.unsigned_8(NETCMD_SETTING_PLAYER);1184 packet.unsigned_8(NETCMD_SETTING_PLAYER);
1184 s.unsigned_8(number);1185 packet.unsigned_8(number);
1185 write_setting_player(s, number);1186 write_setting_player(packet, number);
1186 broadcast(s);1187 broadcast(packet);
1187 return;1188 return;
1188 }1189 }
1189 }1190 }
@@ -1205,11 +1206,11 @@
1205 player.initialization_index = index;1206 player.initialization_index = index;
12061207
1207 // broadcast changes1208 // broadcast changes
1208 SendPacket s;1209 SendPacket packet;
1209 s.unsigned_8(NETCMD_SETTING_PLAYER);1210 packet.unsigned_8(NETCMD_SETTING_PLAYER);
1210 s.unsigned_8(number);1211 packet.unsigned_8(number);
1211 write_setting_player(s, number);1212 write_setting_player(packet, number);
1212 broadcast(s);1213 broadcast(packet);
1213 return;1214 return;
1214 } else1215 } else
1215 log("Attempted to change to out-of-range initialization index %u "1216 log("Attempted to change to out-of-range initialization index %u "
@@ -1230,11 +1231,11 @@
1230 player.random_ai = random_ai;1231 player.random_ai = random_ai;
12311232
1232 // Broadcast changes1233 // Broadcast changes
1233 SendPacket s;1234 SendPacket packet;
1234 s.unsigned_8(NETCMD_SETTING_PLAYER);1235 packet.unsigned_8(NETCMD_SETTING_PLAYER);
1235 s.unsigned_8(number);1236 packet.unsigned_8(number);
1236 write_setting_player(s, number);1237 write_setting_player(packet, number);
1237 broadcast(s);1238 broadcast(packet);
1238}1239}
12391240
1240void GameHost::set_player_name(uint8_t const number, const std::string& name) {1241void GameHost::set_player_name(uint8_t const number, const std::string& name) {
@@ -1249,11 +1250,11 @@
1249 player.name = name;1250 player.name = name;
12501251
1251 // Broadcast changes1252 // Broadcast changes
1252 SendPacket s;1253 SendPacket packet;
1253 s.unsigned_8(NETCMD_SETTING_PLAYER);1254 packet.unsigned_8(NETCMD_SETTING_PLAYER);
1254 s.unsigned_8(number);1255 packet.unsigned_8(number);
1255 write_setting_player(s, number);1256 write_setting_player(packet, number);
1256 broadcast(s);1257 broadcast(packet);
1257}1258}
12581259
1259void GameHost::set_player_closeable(uint8_t const number, bool closeable) {1260void GameHost::set_player_closeable(uint8_t const number, bool closeable) {
@@ -1288,11 +1289,11 @@
1288 player.tribe = sharedplr.tribe;1289 player.tribe = sharedplr.tribe;
12891290
1290 // Broadcast changes1291 // Broadcast changes
1291 SendPacket s;1292 SendPacket packet;
1292 s.unsigned_8(NETCMD_SETTING_PLAYER);1293 packet.unsigned_8(NETCMD_SETTING_PLAYER);
1293 s.unsigned_8(number);1294 packet.unsigned_8(number);
1294 write_setting_player(s, number);1295 write_setting_player(packet, number);
1295 broadcast(s);1296 broadcast(packet);
1296}1297}
12971298
1298void GameHost::set_player(uint8_t const number, const PlayerSettings& ps) {1299void GameHost::set_player(uint8_t const number, const PlayerSettings& ps) {
@@ -1303,11 +1304,11 @@
1303 player = ps;1304 player = ps;
13041305
1305 // Broadcast changes1306 // Broadcast changes
1306 SendPacket s;1307 SendPacket packet;
1307 s.unsigned_8(NETCMD_SETTING_PLAYER);1308 packet.unsigned_8(NETCMD_SETTING_PLAYER);
1308 s.unsigned_8(number);1309 packet.unsigned_8(number);
1309 write_setting_player(s, number);1310 write_setting_player(packet, number);
1310 broadcast(s);1311 broadcast(packet);
1311}1312}
13121313
1313void GameHost::set_player_number(uint8_t const number) {1314void GameHost::set_player_number(uint8_t const number) {
@@ -1318,10 +1319,10 @@
1318 d->settings.win_condition_script = wc;1319 d->settings.win_condition_script = wc;
13191320
1320 // Broadcast changes1321 // Broadcast changes
1321 SendPacket s;1322 SendPacket packet;
1322 s.unsigned_8(NETCMD_WIN_CONDITION);1323 packet.unsigned_8(NETCMD_WIN_CONDITION);
1323 s.string(wc);1324 packet.string(wc);
1324 broadcast(s);1325 broadcast(packet);
1325}1326}
13261327
1327void GameHost::switch_to_player(uint32_t user, uint8_t number) {1328void GameHost::switch_to_player(uint32_t user, uint8_t number) {
@@ -1367,11 +1368,11 @@
1367 }1368 }
13681369
1369 // Broadcast the user changes to everybody1370 // Broadcast the user changes to everybody
1370 SendPacket s;1371 SendPacket packet;
1371 s.unsigned_8(NETCMD_SETTING_USER);1372 packet.unsigned_8(NETCMD_SETTING_USER);
1372 s.unsigned_32(user);1373 packet.unsigned_32(user);
1373 write_setting_user(s, user);1374 write_setting_user(packet, user);
1374 broadcast(s);1375 broadcast(packet);
1375}1376}
13761377
1377void GameHost::set_player_team(uint8_t number, Widelands::TeamNumber team) {1378void GameHost::set_player_team(uint8_t number, Widelands::TeamNumber team) {
@@ -1380,11 +1381,11 @@
1380 d->settings.players.at(number).team = team;1381 d->settings.players.at(number).team = team;
13811382
1382 // Broadcast changes1383 // Broadcast changes
1383 SendPacket s;1384 SendPacket packet;
1384 s.unsigned_8(NETCMD_SETTING_PLAYER);1385 packet.unsigned_8(NETCMD_SETTING_PLAYER);
1385 s.unsigned_8(number);1386 packet.unsigned_8(number);
1386 write_setting_player(s, number);1387 write_setting_player(packet, number);
1387 broadcast(s);1388 broadcast(packet);
1388}1389}
13891390
1390void GameHost::set_multiplayer_game_settings() {1391void GameHost::set_multiplayer_game_settings() {
@@ -1476,11 +1477,11 @@
1476}1477}
14771478
1478/**1479/**
1479* If possible, this function writes the MapTransferInfo to SendPacket & s1480* If possible, this function writes the MapTransferInfo to SendPacket & packet
1480*1481*
1481* \returns true if the data was written, else false1482* \returns true if the data was written, else false
1482*/1483*/
1483bool GameHost::write_map_transfer_info(SendPacket& s, std::string mapfilename) {1484bool GameHost::write_map_transfer_info(SendPacket& packet, std::string mapfilename) {
1484 // TODO(unknown): not yet able to handle directory type maps / savegames1485 // TODO(unknown): not yet able to handle directory type maps / savegames
1485 if (g_fs->is_directory(mapfilename)) {1486 if (g_fs->is_directory(mapfilename)) {
1486 log("Map/Save is a directory! No way for making it available a.t.m.!\n");1487 log("Map/Save is a directory! No way for making it available a.t.m.!\n");
@@ -1489,13 +1490,13 @@
14891490
1490 // Write the new map/save file information, so client can decide whether it1491 // Write the new map/save file information, so client can decide whether it
1491 // needs the file.1492 // needs the file.
1492 s.unsigned_8(NETCMD_NEW_FILE_AVAILABLE);1493 packet.unsigned_8(NETCMD_NEW_FILE_AVAILABLE);
1493 s.string(mapfilename);1494 packet.string(mapfilename);
1494 // Scan-build reports that access to bytes here results in a dereference of null pointer.1495 // Scan-build reports that access to bytes here results in a dereference of null pointer.
1495 // This is a false positive.1496 // This is a false positive.
1496 // See https://bugs.launchpad.net/widelands/+bug/11989191497 // See https://bugs.launchpad.net/widelands/+bug/1198919
1497 s.unsigned_32(file_->bytes); // NOLINT1498 packet.unsigned_32(file_->bytes); // NOLINT
1498 s.string(file_->md5sum);1499 packet.string(file_->md5sum);
1499 return true;1500 return true;
1500}1501}
15011502
@@ -1579,62 +1580,63 @@
15791580
1580 log("[Host]: Client %u: welcome to usernum %u\n", number, client.usernum);1581 log("[Host]: Client %u: welcome to usernum %u\n", number, client.usernum);
15811582
1582 SendPacket s;1583 SendPacket packet;
1583 s.unsigned_8(NETCMD_HELLO);1584 packet.unsigned_8(NETCMD_HELLO);
1584 s.unsigned_8(NETWORK_PROTOCOL_VERSION);1585 packet.unsigned_8(NETWORK_PROTOCOL_VERSION);
1585 s.unsigned_32(client.usernum);1586 packet.unsigned_32(client.usernum);
1586 d->net->send(client.sock_id, s);1587 d->net->send(client.sock_id, packet);
1587 // even if the network protocol is the same, the data might be different.1588 // even if the network protocol is the same, the data might be different.
1588 if (client.build_id != build_id())1589 if (client.build_id != build_id())
1589 send_system_message_code("DIFFERENT_WL_VERSION", effective_name, client.build_id, build_id());1590 send_system_message_code("DIFFERENT_WL_VERSION", effective_name, client.build_id, build_id());
1590 // Send information about currently selected map / savegame1591 // Send information about currently selected map / savegame
1591 s.reset();1592 packet.reset();
15921593
1593 s.unsigned_8(NETCMD_SETTING_MAP);1594 packet.unsigned_8(NETCMD_SETTING_MAP);
1594 write_setting_map(s);1595 write_setting_map(packet);
1595 d->net->send(client.sock_id, s);1596 d->net->send(client.sock_id, packet);
15961597
1597 // If possible, offer the map / savegame as transfer1598 // If possible, offer the map / savegame as transfer
1598 if (file_) {1599 if (file_) {
1599 s.reset();1600 packet.reset();
1600 if (write_map_transfer_info(s, file_->filename))1601 if (write_map_transfer_info(packet, file_->filename)) {
1601 d->net->send(client.sock_id, s);1602 d->net->send(client.sock_id, packet);
1603 }
1602 }1604 }
16031605
1604 // Send the tribe information to the new client.1606 // Send the tribe information to the new client.
1605 s.reset();1607 packet.reset();
1606 s.unsigned_8(NETCMD_SETTING_TRIBES);1608 packet.unsigned_8(NETCMD_SETTING_TRIBES);
1607 s.unsigned_8(d->settings.tribes.size());1609 packet.unsigned_8(d->settings.tribes.size());
1608 for (const TribeBasicInfo& tribe : d->settings.tribes) {1610 for (const TribeBasicInfo& tribe : d->settings.tribes) {
1609 s.string(tribe.name);1611 packet.string(tribe.name);
1610 size_t const nr_initializations = tribe.initializations.size();1612 size_t const nr_initializations = tribe.initializations.size();
1611 s.unsigned_8(nr_initializations);1613 packet.unsigned_8(nr_initializations);
1612 for (const TribeBasicInfo::Initialization& init : tribe.initializations)1614 for (const TribeBasicInfo::Initialization& init : tribe.initializations)
1613 s.string(init.script);1615 packet.string(init.script);
1614 }1616 }
1615 d->net->send(client.sock_id, s);1617 d->net->send(client.sock_id, packet);
16161618
1617 s.reset();1619 packet.reset();
1618 s.unsigned_8(NETCMD_SETTING_ALLPLAYERS);1620 packet.unsigned_8(NETCMD_SETTING_ALLPLAYERS);
1619 write_setting_all_players(s);1621 write_setting_all_players(packet);
1620 d->net->send(client.sock_id, s);1622 d->net->send(client.sock_id, packet);
16211623
1622 s.reset();1624 packet.reset();
1623 s.unsigned_8(NETCMD_SETTING_ALLUSERS);1625 packet.unsigned_8(NETCMD_SETTING_ALLUSERS);
1624 write_setting_all_users(s);1626 write_setting_all_users(packet);
1625 d->net->send(client.sock_id, s);1627 d->net->send(client.sock_id, packet);
16261628
1627 s.reset();1629 packet.reset();
1628 s.unsigned_8(NETCMD_WIN_CONDITION);1630 packet.unsigned_8(NETCMD_WIN_CONDITION);
1629 s.string(d->settings.win_condition_script);1631 packet.string(d->settings.win_condition_script);
1630 d->net->send(client.sock_id, s);1632 d->net->send(client.sock_id, packet);
16311633
1632 // Broadcast new information about the player to everybody1634 // Broadcast new information about the player to everybody
1633 s.reset();1635 packet.reset();
1634 s.unsigned_8(NETCMD_SETTING_USER);1636 packet.unsigned_8(NETCMD_SETTING_USER);
1635 s.unsigned_32(client.usernum);1637 packet.unsigned_32(client.usernum);
1636 write_setting_user(s, client.usernum);1638 write_setting_user(packet, client.usernum);
1637 broadcast(s);1639 broadcast(packet);
16381640
1639 // Check if there is an unoccupied player left and if, assign.1641 // Check if there is an unoccupied player left and if, assign.
1640 for (uint8_t i = 0; i < d->settings.players.size(); ++i)1642 for (uint8_t i = 0; i < d->settings.players.size(); ++i)
@@ -1731,9 +1733,9 @@
1731 d->waiting = true;1733 d->waiting = true;
1732 broadcast_real_speed(0);1734 broadcast_real_speed(0);
17331735
1734 SendPacket s;1736 SendPacket packet;
1735 s.unsigned_8(NETCMD_WAIT);1737 packet.unsigned_8(NETCMD_WAIT);
1736 broadcast(s);1738 broadcast(packet);
1737 }1739 }
1738 } else {1740 } else {
1739 if (nrdelayed == 0) {1741 if (nrdelayed == 0) {
@@ -1748,10 +1750,10 @@
1748void GameHost::broadcast_real_speed(uint32_t const speed) {1750void GameHost::broadcast_real_speed(uint32_t const speed) {
1749 assert(speed <= std::numeric_limits<uint16_t>::max());1751 assert(speed <= std::numeric_limits<uint16_t>::max());
17501752
1751 SendPacket s;1753 SendPacket packet;
1752 s.unsigned_8(NETCMD_SETSPEED);1754 packet.unsigned_8(NETCMD_SETSPEED);
1753 s.unsigned_16(speed);1755 packet.unsigned_16(speed);
1754 broadcast(s);1756 broadcast(packet);
1755}1757}
17561758
1757/**1759/**
@@ -1829,10 +1831,10 @@
18291831
1830 log("[Host]: Requesting sync reports for time %i\n", d->syncreport_time);1832 log("[Host]: Requesting sync reports for time %i\n", d->syncreport_time);
18311833
1832 SendPacket s;1834 SendPacket packet;
1833 s.unsigned_8(NETCMD_SYNCREQUEST);1835 packet.unsigned_8(NETCMD_SYNCREQUEST);
1834 s.signed_32(d->syncreport_time);1836 packet.signed_32(d->syncreport_time);
1835 broadcast(s);1837 broadcast(packet);
18361838
1837 d->game->enqueue_command(1839 d->game->enqueue_command(
1838 new CmdNetCheckSync(d->syncreport_time, [this] { sync_report_callback(); }));1840 new CmdNetCheckSync(d->syncreport_time, [this] { sync_report_callback(); }));
@@ -1870,9 +1872,9 @@
18701872
1871 d->game->save_syncstream(true);1873 d->game->save_syncstream(true);
18721874
1873 SendPacket s;1875 SendPacket packet;
1874 s.unsigned_8(NETCMD_INFO_DESYNC);1876 packet.unsigned_8(NETCMD_INFO_DESYNC);
1875 broadcast(s);1877 broadcast(packet);
18761878
1877 disconnect_client(i, "CLIENT_DESYNCED");1879 disconnect_client(i, "CLIENT_DESYNCED");
1878 // Pause the game, so that host and client have time to handle the1880 // Pause the game, so that host and client have time to handle the
@@ -1948,9 +1950,9 @@
1948 if ((forced_pause_ || real_speed() == 0) && (time(nullptr) > (d->lastpauseping + 20))) {1950 if ((forced_pause_ || real_speed() == 0) && (time(nullptr) > (d->lastpauseping + 20))) {
1949 d->lastpauseping = time(nullptr);1951 d->lastpauseping = time(nullptr);
19501952
1951 SendPacket s;1953 SendPacket send_packet;
1952 s.unsigned_8(NETCMD_PING);1954 send_packet.unsigned_8(NETCMD_PING);
1953 broadcast(s);1955 broadcast(send_packet);
1954 }1956 }
19551957
1956 reaper();1958 reaper();
@@ -1984,9 +1986,9 @@
1984 if (cmd == NETCMD_METASERVER_PING) {1986 if (cmd == NETCMD_METASERVER_PING) {
1985 log("[Host]: Received ping from metaserver.\n");1987 log("[Host]: Received ping from metaserver.\n");
1986 // Send PING back1988 // Send PING back
1987 SendPacket s;1989 SendPacket packet;
1988 s.unsigned_8(NETCMD_METASERVER_PING);1990 packet.unsigned_8(NETCMD_METASERVER_PING);
1989 d->net->send(client.sock_id, s);1991 d->net->send(client.sock_id, packet);
19901992
1991 // Remove metaserver from list of clients1993 // Remove metaserver from list of clients
1992 client.playernum = UserSettings::not_connected();1994 client.playernum = UserSettings::not_connected();
@@ -2155,11 +2157,11 @@
2155 send_file_part(client.sock_id, 0);2157 send_file_part(client.sock_id, 0);
2156 // Remember client as "currently receiving file"2158 // Remember client as "currently receiving file"
2157 d->settings.users[client.usernum].ready = false;2159 d->settings.users[client.usernum].ready = false;
2158 SendPacket s;2160 SendPacket packet;
2159 s.unsigned_8(NETCMD_SETTING_USER);2161 packet.unsigned_8(NETCMD_SETTING_USER);
2160 s.unsigned_32(client.usernum);2162 packet.unsigned_32(client.usernum);
2161 write_setting_user(s, client.usernum);2163 write_setting_user(packet, client.usernum);
2162 broadcast(s);2164 broadcast(packet);
2163 break;2165 break;
2164 }2166 }
21652167
@@ -2179,11 +2181,11 @@
2179 send_system_message_code(2181 send_system_message_code(
2180 "COMPLETED_FILE_TRANSFER", file_->filename, d->settings.users.at(client.usernum).name);2182 "COMPLETED_FILE_TRANSFER", file_->filename, d->settings.users.at(client.usernum).name);
2181 d->settings.users[client.usernum].ready = true;2183 d->settings.users[client.usernum].ready = true;
2182 SendPacket s;2184 SendPacket packet;
2183 s.unsigned_8(NETCMD_SETTING_USER);2185 packet.unsigned_8(NETCMD_SETTING_USER);
2184 s.unsigned_32(client.usernum);2186 packet.unsigned_32(client.usernum);
2185 write_setting_user(s, client.usernum);2187 write_setting_user(packet, client.usernum);
2186 broadcast(s);2188 broadcast(packet);
2187 return;2189 return;
2188 }2190 }
2189 ++part;2191 ++part;
@@ -2207,12 +2209,12 @@
2207 uint32_t size = (left > NETFILEPARTSIZE) ? NETFILEPARTSIZE : left;2209 uint32_t size = (left > NETFILEPARTSIZE) ? NETFILEPARTSIZE : left;
22082210
2209 // Send the part2211 // Send the part
2210 SendPacket s;2212 SendPacket packet;
2211 s.unsigned_8(NETCMD_FILE_PART);2213 packet.unsigned_8(NETCMD_FILE_PART);
2212 s.unsigned_32(part);2214 packet.unsigned_32(part);
2213 s.unsigned_32(size);2215 packet.unsigned_32(size);
2214 s.data(file_->parts[part].part, size);2216 packet.data(file_->parts[part].part, size);
2215 d->net->send(csock_id, s);2217 d->net->send(csock_id, packet);
2216}2218}
22172219
2218void GameHost::disconnect_player_controller(uint8_t const number, const std::string& name) {2220void GameHost::disconnect_player_controller(uint8_t const number, const std::string& name) {
@@ -2265,11 +2267,11 @@
2265 send_system_message_code(2267 send_system_message_code(
2266 "CLIENT_X_LEFT_GAME", d->settings.users.at(client.usernum).name, reason, arg);2268 "CLIENT_X_LEFT_GAME", d->settings.users.at(client.usernum).name, reason, arg);
22672269
2268 SendPacket s;2270 SendPacket packet;
2269 s.unsigned_8(NETCMD_SETTING_USER);2271 packet.unsigned_8(NETCMD_SETTING_USER);
2270 s.unsigned_32(client.usernum);2272 packet.unsigned_32(client.usernum);
2271 write_setting_user(s, client.usernum);2273 write_setting_user(packet, client.usernum);
2272 broadcast(s);2274 broadcast(packet);
2273 } else2275 } else
2274 send_system_message_code("UNKNOWN_LEFT_GAME", reason, arg);2276 send_system_message_code("UNKNOWN_LEFT_GAME", reason, arg);
22752277
@@ -2277,13 +2279,14 @@
22772279
2278 if (client.sock_id > 0) {2280 if (client.sock_id > 0) {
2279 if (sendreason) {2281 if (sendreason) {
2280 SendPacket s;2282 SendPacket packet;
2281 s.unsigned_8(NETCMD_DISCONNECT);2283 packet.unsigned_8(NETCMD_DISCONNECT);
2282 s.unsigned_8(arg.empty() ? 1 : 2);2284 packet.unsigned_8(arg.empty() ? 1 : 2);
2283 s.string(reason);2285 packet.string(reason);
2284 if (!arg.empty())2286 if (!arg.empty()) {
2285 s.string(arg);2287 packet.string(arg);
2286 d->net->send(client.sock_id, s);2288 }
2289 d->net->send(client.sock_id, packet);
2287 }2290 }
22882291
2289 d->net->close(client.sock_id);2292 d->net->close(client.sock_id);
22902293
=== modified file 'src/wui/multiplayersetupgroup.cc'
--- src/wui/multiplayersetupgroup.cc 2017-09-02 21:48:44 +0000
+++ src/wui/multiplayersetupgroup.cc 2017-11-27 07:16:30 +0000
@@ -61,7 +61,7 @@
61 // Name needs to be initialized after the dropdown, otherwise the layout function will61 // Name needs to be initialized after the dropdown, otherwise the layout function will
62 // crash.62 // crash.
63 name(this, 0, 0, w - h - UI::Scrollbar::kSize * 11 / 5, h),63 name(this, 0, 0, w - h - UI::Scrollbar::kSize * 11 / 5, h),
64 s(settings),64 settings_(settings),
65 id_(id),65 id_(id),
66 slot_selection_locked_(false) {66 slot_selection_locked_(false) {
67 set_size(w, h);67 set_size(w, h);
@@ -106,7 +106,7 @@
106 /// This will update the client's player slot with the value currently selected in the slot106 /// This will update the client's player slot with the value currently selected in the slot
107 /// dropdown.107 /// dropdown.
108 void set_slot() {108 void set_slot() {
109 const GameSettings& settings = s->settings();109 const GameSettings& settings = settings_->settings();
110 if (id_ != settings.usernum) {110 if (id_ != settings.usernum) {
111 return;111 return;
112 }112 }
@@ -114,7 +114,7 @@
114 if (slot_dropdown_.has_selection()) {114 if (slot_dropdown_.has_selection()) {
115 const uint8_t new_slot = slot_dropdown_.get_selected();115 const uint8_t new_slot = slot_dropdown_.get_selected();
116 if (new_slot != settings.users.at(id_).position) {116 if (new_slot != settings.users.at(id_).position) {
117 s->set_player_number(slot_dropdown_.get_selected());117 settings_->set_player_number(slot_dropdown_.get_selected());
118 }118 }
119 }119 }
120 slot_selection_locked_ = false;120 slot_selection_locked_ = false;
@@ -147,7 +147,7 @@
147147
148 /// Take care of visibility and current values148 /// Take care of visibility and current values
149 void update() {149 void update() {
150 const GameSettings& settings = s->settings();150 const GameSettings& settings = settings_->settings();
151 const UserSettings& user_setting = settings.users.at(id_);151 const UserSettings& user_setting = settings.users.at(id_);
152152
153 if (user_setting.position == UserSettings::not_connected()) {153 if (user_setting.position == UserSettings::not_connected()) {
@@ -161,7 +161,7 @@
161161
162 UI::Dropdown<uintptr_t> slot_dropdown_; /// Select the player slot.162 UI::Dropdown<uintptr_t> slot_dropdown_; /// Select the player slot.
163 UI::Textarea name; /// Client nick name163 UI::Textarea name; /// Client nick name
164 GameSettingsProvider* const s;164 GameSettingsProvider* const settings_;
165 uint8_t const id_; /// User number165 uint8_t const id_; /// User number
166 bool slot_selection_locked_; // Ensure that dropdowns will close on selection.166 bool slot_selection_locked_; // Ensure that dropdowns will close on selection.
167 std::unique_ptr<Notifications::Subscriber<NoteGameSettings>> subscriber_;167 std::unique_ptr<Notifications::Subscriber<NoteGameSettings>> subscriber_;
@@ -176,7 +176,7 @@
176 GameSettingsProvider* const settings,176 GameSettingsProvider* const settings,
177 NetworkPlayerSettingsBackend* const npsb)177 NetworkPlayerSettingsBackend* const npsb)
178 : UI::Box(parent, 0, 0, UI::Box::Horizontal, w, h, kPadding / 2),178 : UI::Box(parent, 0, 0, UI::Box::Horizontal, w, h, kPadding / 2),
179 s(settings),179 settings_(settings),
180 n(npsb),180 n(npsb),
181 id_(id),181 id_(id),
182 player(this,182 player(this,
@@ -227,23 +227,26 @@
227 add_space(0);227 add_space(0);
228228
229 subscriber_ =229 subscriber_ =
230 Notifications::subscribe<NoteGameSettings>([this](const NoteGameSettings& note) {230 Notifications::subscribe<NoteGameSettings>(
231 switch (note.action) {231 [this](const NoteGameSettings& note) {
232 case NoteGameSettings::Action::kMap:232 const std::vector<PlayerSettings> & players = settings_->settings().players;
233 // We don't care about map updates, since we receive enough notifications for the233 switch (note.action) {
234 // slots.234 case NoteGameSettings::Action::kMap:
235 break;235 // We don't care about map updates, since we receive enough notifications for the
236 default:236 // slots.
237 if (s->settings().players.empty()) {237 break;
238 // No map/savegame yet238 default:
239 return;239 if (players.empty()) {
240 }240 // No map/savegame yet
241 if (id_ == note.position ||241 return;
242 s->settings().players[id_].state == PlayerSettings::State::kShared) {242 }
243 update();243 if (id_ == note.position ||
244 }244 (id_ < players.size() &&
245 }245 players.at(id_).state == PlayerSettings::State::kShared)) {
246 });246 update();
247 }
248 }
249 });
247250
248 // Init dropdowns251 // Init dropdowns
249 update();252 update();
@@ -263,7 +266,7 @@
263 /// This will update the game settings for the type with the value266 /// This will update the game settings for the type with the value
264 /// currently selected in the type dropdown.267 /// currently selected in the type dropdown.
265 void set_type() {268 void set_type() {
266 if (!s->can_change_player_state(id_)) {269 if (!settings_->can_change_player_state(id_)) {
267 return;270 return;
268 }271 }
269 type_selection_locked_ = true;272 type_selection_locked_ = true;
@@ -328,7 +331,7 @@
328 type_dropdown_.add(331 type_dropdown_.add(
329 _("Open"), "open", g_gr->images().get("images/ui_basic/continue.png"), false, _("Open"));332 _("Open"), "open", g_gr->images().get("images/ui_basic/continue.png"), false, _("Open"));
330333
331 type_dropdown_.set_enabled(s->can_change_player_state(id_));334 type_dropdown_.set_enabled(settings_->can_change_player_state(id_));
332335
333 // Now select the entry according to server settings336 // Now select the entry according to server settings
334 const PlayerSettings& player_setting = settings.players[id_];337 const PlayerSettings& player_setting = settings.players[id_];
@@ -360,9 +363,9 @@
360363
361 /// Whether the client who is running the UI is allowed to change the tribe for this player slot.364 /// Whether the client who is running the UI is allowed to change the tribe for this player slot.
362 bool has_tribe_access() {365 bool has_tribe_access() {
363 return s->settings().players[id_].state == PlayerSettings::State::kShared ?366 return settings_->settings().players[id_].state == PlayerSettings::State::kShared ?
364 s->can_change_player_init(id_) :367 settings_->can_change_player_init(id_) :
365 s->can_change_player_tribe(id_);368 settings_->can_change_player_tribe(id_);
366 }369 }
367370
368 /// This will update the game settings for the tribe or shared_in with the value371 /// This will update the game settings for the tribe or shared_in with the value
@@ -371,7 +374,7 @@
371 if (!has_tribe_access()) {374 if (!has_tribe_access()) {
372 return;375 return;
373 }376 }
374 const PlayerSettings& player_settings = s->settings().players[id_];377 const PlayerSettings& player_settings = settings_->settings().players[id_];
375 tribe_selection_locked_ = true;378 tribe_selection_locked_ = true;
376 tribes_dropdown_.set_disable_style(player_settings.state == PlayerSettings::State::kShared ?379 tribes_dropdown_.set_disable_style(player_settings.state == PlayerSettings::State::kShared ?
377 UI::ButtonDisableStyle::kPermpressed :380 UI::ButtonDisableStyle::kPermpressed :
@@ -451,7 +454,7 @@
451 /// This will update the game settings for the initialization with the value454 /// This will update the game settings for the initialization with the value
452 /// currently selected in the initialization dropdown.455 /// currently selected in the initialization dropdown.
453 void set_init() {456 void set_init() {
454 if (!s->can_change_player_init(id_)) {457 if (!settings_->can_change_player_init(id_)) {
455 return;458 return;
456 }459 }
457 init_selection_locked_ = true;460 init_selection_locked_ = true;
@@ -487,7 +490,7 @@
487 }490 }
488491
489 init_dropdown_.set_visible(true);492 init_dropdown_.set_visible(true);
490 init_dropdown_.set_enabled(s->can_change_player_init(id_));493 init_dropdown_.set_enabled(settings_->can_change_player_init(id_));
491 }494 }
492495
493 /// This will update the team settings with the value currently selected in the teams dropdown.496 /// This will update the team settings with the value currently selected in the teams dropdown.
@@ -524,12 +527,12 @@
524 }527 }
525 team_dropdown_.select(player_setting.team);528 team_dropdown_.select(player_setting.team);
526 team_dropdown_.set_visible(true);529 team_dropdown_.set_visible(true);
527 team_dropdown_.set_enabled(s->can_change_player_team(id_));530 team_dropdown_.set_enabled(settings_->can_change_player_team(id_));
528 }531 }
529532
530 /// Refresh all user interfaces533 /// Refresh all user interfaces
531 void update() {534 void update() {
532 const GameSettings& settings = s->settings();535 const GameSettings& settings = settings_->settings();
533 if (id_ >= settings.players.size()) {536 if (id_ >= settings.players.size()) {
534 set_visible(false);537 set_visible(false);
535 return;538 return;
@@ -556,7 +559,7 @@
556 // Trigger update for the other players for shared_in mode when slots open and close559 // Trigger update for the other players for shared_in mode when slots open and close
557 if (last_state_ != player_setting.state) {560 if (last_state_ != player_setting.state) {
558 last_state_ = player_setting.state;561 last_state_ = player_setting.state;
559 for (PlayerSlot slot = 0; slot < s->settings().players.size(); ++slot) {562 for (PlayerSlot slot = 0; slot < settings_->settings().players.size(); ++slot) {
560 if (slot != id_) {563 if (slot != id_) {
561 n->set_player_state(slot, settings.players[slot].state);564 n->set_player_state(slot, settings.players[slot].state);
562 }565 }
@@ -564,7 +567,7 @@
564 }567 }
565 }568 }
566569
567 GameSettingsProvider* const s;570 GameSettingsProvider* const settings_;
568 NetworkPlayerSettingsBackend* const n;571 NetworkPlayerSettingsBackend* const n;
569 PlayerSlot const id_;572 PlayerSlot const id_;
570573
@@ -594,8 +597,8 @@
594 GameSettingsProvider* const settings,597 GameSettingsProvider* const settings,
595 uint32_t buth)598 uint32_t buth)
596 : UI::Box(parent, x, y, UI::Box::Horizontal, w, h, 8 * kPadding),599 : UI::Box(parent, x, y, UI::Box::Horizontal, w, h, 8 * kPadding),
597 s(settings),600 settings_(settings),
598 npsb(new NetworkPlayerSettingsBackend(s)),601 npsb(new NetworkPlayerSettingsBackend(settings_)),
599 clientbox(this, 0, 0, UI::Box::Vertical),602 clientbox(this, 0, 0, UI::Box::Vertical),
600 playerbox(this, 0, 0, UI::Box::Vertical, w * 9 / 15, h, kPadding),603 playerbox(this, 0, 0, UI::Box::Vertical, w * 9 / 15, h, kPadding),
601 buth_(buth) {604 buth_(buth) {
@@ -611,7 +614,7 @@
611 multi_player_player_groups.resize(kMaxPlayers);614 multi_player_player_groups.resize(kMaxPlayers);
612 for (PlayerSlot i = 0; i < multi_player_player_groups.size(); ++i) {615 for (PlayerSlot i = 0; i < multi_player_player_groups.size(); ++i) {
613 multi_player_player_groups.at(i) =616 multi_player_player_groups.at(i) =
614 new MultiPlayerPlayerGroup(&playerbox, playerbox.get_w(), buth_, i, s, npsb.get());617 new MultiPlayerPlayerGroup(&playerbox, playerbox.get_w(), buth_, i, settings, npsb.get());
615 playerbox.add(multi_player_player_groups.at(i));618 playerbox.add(multi_player_player_groups.at(i));
616 }619 }
617 playerbox.add_space(0);620 playerbox.add_space(0);
@@ -627,7 +630,7 @@
627630
628/// Update which slots are available based on current settings.631/// Update which slots are available based on current settings.
629void MultiPlayerSetupGroup::update() {632void MultiPlayerSetupGroup::update() {
630 const GameSettings& settings = s->settings();633 const GameSettings& settings = settings_->settings();
631634
632 // Update / initialize client groups635 // Update / initialize client groups
633 if (multi_player_client_groups.size() < settings.users.size()) {636 if (multi_player_client_groups.size() < settings.users.size()) {
@@ -636,7 +639,7 @@
636 for (uint32_t i = 0; i < settings.users.size(); ++i) {639 for (uint32_t i = 0; i < settings.users.size(); ++i) {
637 if (!multi_player_client_groups.at(i)) {640 if (!multi_player_client_groups.at(i)) {
638 multi_player_client_groups.at(i) =641 multi_player_client_groups.at(i) =
639 new MultiPlayerClientGroup(&clientbox, clientbox.get_w(), buth_, i, s);642 new MultiPlayerClientGroup(&clientbox, clientbox.get_w(), buth_, i, settings_);
640 clientbox.add(multi_player_client_groups.at(i), UI::Box::Resizing::kFullSize);643 clientbox.add(multi_player_client_groups.at(i), UI::Box::Resizing::kFullSize);
641 multi_player_client_groups.at(i)->layout();644 multi_player_client_groups.at(i)->layout();
642 }645 }
643646
=== modified file 'src/wui/multiplayersetupgroup.h'
--- src/wui/multiplayersetupgroup.h 2017-06-26 11:32:11 +0000
+++ src/wui/multiplayersetupgroup.h 2017-11-27 07:16:30 +0000
@@ -57,7 +57,7 @@
57 void update();57 void update();
58 void draw(RenderTarget& dst) override;58 void draw(RenderTarget& dst) override;
5959
60 GameSettingsProvider* const s;60 GameSettingsProvider* const settings_;
61 std::unique_ptr<NetworkPlayerSettingsBackend> npsb;61 std::unique_ptr<NetworkPlayerSettingsBackend> npsb;
62 std::vector<MultiPlayerClientGroup*> multi_player_client_groups; // not owned62 std::vector<MultiPlayerClientGroup*> multi_player_client_groups; // not owned
63 std::vector<MultiPlayerPlayerGroup*> multi_player_player_groups; // not owned63 std::vector<MultiPlayerPlayerGroup*> multi_player_player_groups; // not owned

Subscribers

People subscribed via source and target branches

to status/vote changes: