Ticket #2447: readyv3.patch
File readyv3.patch, 26.3 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/gui/common/modern/sprites.xml
296 296 size="0 0 22 22" 297 297 /> 298 298 </sprite> 299 <sprite name="ModernCheckOn"> 300 <image texture="global/modern/checkbox-on.png" 301 real_texture_placement="0 0 32 32" 302 /> 303 </sprite> 304 <sprite name="ModernCheckOff"> 305 <image texture="global/modern/checkbox-off.png" 306 real_texture_placement="0 0 32 32" 307 /> 308 </sprite> 299 309 </sprites> -
binaries/data/mods/public/gui/gamesetup/gamesetup.js
31 31 // (and therefore shouldn't send further messages to the network) 32 32 var g_IsInGuiUpdate; 33 33 34 // Is this user ready 35 var g_IsReady; 36 34 37 var g_PlayerAssignments = {}; 35 38 36 39 // Default game setup attributes … … 97 100 { 98 101 cancelButton.tooltip = "Return to the lobby." 99 102 } 100 103 if (!g_IsNetworked) 104 Engine.GetGUIObjectByName("toggleReady").hidden = true; 101 105 } 102 106 103 107 // Called after the map data is loaded and cached … … 412 416 break; 413 417 414 418 case "players": 419 var playersChanged = false; 415 420 // Find and report all joinings/leavings 416 421 for (var host in message.hosts) 417 422 if (! g_PlayerAssignments[host]) 423 { 418 424 addChatMessage({ "type": "connect", "username": message.hosts[host].name }); 425 playersChanged = true; 426 } 419 427 420 428 for (var host in g_PlayerAssignments) 421 429 if (! message.hosts[host]) 430 { 422 431 addChatMessage({ "type": "disconnect", "guid": host }); 432 playersChanged = true; 433 } 423 434 424 435 // Update the player list 425 436 g_PlayerAssignments = message.hosts; 437 if (playersChanged) 438 resetReadyData(); 439 updateReadyUI(); 426 440 updatePlayerList(); 427 428 441 if (g_IsController) 429 442 sendRegisterGameStanza(); 430 443 break; … … 447 460 addChatMessage({ "type": "message", "guid": message.guid, "text": message.text }); 448 461 break; 449 462 463 // Singular client to host message 464 case "ready": 465 if (!g_IsController) 466 break; 467 g_PlayerAssignments[message.guid].status = (parseInt(message.text) == 1); 468 Engine.AssignNetworkPlayerStatus(parseInt(message.text), message.guid); 469 updateReadyUI(); 470 break; 471 450 472 default: 451 473 error("Unrecognised net message type "+message.type); 452 474 } … … 705 727 if (g_IsNetworked) 706 728 Engine.AssignNetworkPlayer(player, ""); 707 729 else 708 g_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1 } };730 g_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1, "ready": 0} }; 709 731 } 710 732 } 711 733 … … 822 844 // Reset player assignments on map change 823 845 if (!g_IsNetworked) 824 846 { // Slot 1 825 g_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1 } };847 g_PlayerAssignments = { "local": { "name": "You", "player": 1, "civ": "", "team": -1, "ready": 0} }; 826 848 } 827 849 else 828 850 { … … 842 864 843 865 function launchGame() 844 866 { 867 if (g_IsNetworked && !g_IsReady) 868 { 869 for (var guid in g_PlayerAssignments) 870 { 871 if (g_PlayerAssignments[guid].name.split(" (")[0] == Engine.ConfigDB_GetValue("user", "playername") && g_PlayerAssignments[guid].player == -1) 872 break; // Observers don't need to be ready. 873 else 874 return; // Host may have changed their own code. 875 } 876 } 845 877 if (g_IsNetworked && !g_IsController) 846 878 { 847 879 error("Only host can start game"); … … 1184 1216 if (i >= numPlayers) 1185 1217 continue; 1186 1218 1187 var pName = Engine.GetGUIObjectByName("playerName["+i+"]");1188 1219 var pCiv = Engine.GetGUIObjectByName("playerCiv["+i+"]"); 1189 1220 var pCivText = Engine.GetGUIObjectByName("playerCivText["+i+"]"); 1190 1221 var pTeam = Engine.GetGUIObjectByName("playerTeam["+i+"]"); … … 1198 1229 // Common to all game types 1199 1230 var color = iColorToString(getSetting(pData, pDefs, "Colour")); 1200 1231 pColor.sprite = "colour:"+color+" 100"; 1201 pName.caption = getSetting(pData, pDefs, "Name");1202 1232 1203 1233 var team = getSetting(pData, pDefs, "Team"); 1204 1234 var civ = getSetting(pData, pDefs, "Civ"); … … 1235 1265 1236 1266 // Game attributes include AI settings, so update the player list 1237 1267 updatePlayerList(); 1268 1269 // We should have everyone confirm that the new settings are acceptable. 1270 resetReadyData(); 1238 1271 } 1239 1272 1240 1273 function updateGameAttributes() … … 1404 1437 swapPlayers(guid, playerSlot); 1405 1438 1406 1439 Engine.SetNetworkGameAttributes(g_GameAttributes); 1440 updateReadyUI(); 1407 1441 } 1408 1442 }; 1409 1443 } … … 1534 1568 Engine.GetGUIObjectByName("moreOptions").hidden = !Engine.GetGUIObjectByName("moreOptions").hidden; 1535 1569 } 1536 1570 1571 function toggleReady() 1572 { 1573 g_IsReady = !g_IsReady; 1574 if (g_IsReady) 1575 Engine.SendNetworkReady(1); 1576 else 1577 Engine.SendNetworkReady(0); 1578 } 1579 1580 function updateReadyUI() 1581 { 1582 var allReady = true; 1583 for (var guid in g_PlayerAssignments) 1584 { 1585 // We don't really care whether observers are ready. 1586 if (g_PlayerAssignments[guid].player == -1) 1587 return; 1588 if (g_PlayerAssignments[guid].status || !g_IsNetworked) 1589 Engine.GetGUIObjectByName("playerReadySprite[" + String(g_PlayerAssignments[guid].player - 1) + "]").sprite = "ModernCheckOn"; 1590 else 1591 { 1592 Engine.GetGUIObjectByName("playerReadySprite[" + String(g_PlayerAssignments[guid].player - 1) + "]").sprite = "ModernCheckOff"; 1593 allReady = false; 1594 } 1595 } 1596 // AIs are always ready. 1597 for (var playerid = 0; playerid < MAX_PLAYERS; playerid++) 1598 { 1599 if (g_GameAttributes.settings.PlayerData[playerid]) 1600 { 1601 if (g_GameAttributes.settings.PlayerData[playerid].AI != "" || g_GameAttributes.settings.PlayerData[playerid].Name == "Unassigned") 1602 Engine.GetGUIObjectByName("playerReadySprite[" + String(playerid) + "]").sprite = "ModernCheckOn"; 1603 } 1604 } 1605 1606 // The host is not allowed to start until everyone is ready. 1607 if (g_IsNetworked && g_IsController) 1608 Engine.GetGUIObjectByName("startGame").enabled = allReady; 1609 } 1610 1611 function resetReadyData() 1612 { 1613 g_IsReady = false; 1614 if (g_IsNetworked && g_IsController) 1615 Engine.ClearAllPlayerReady(); 1616 } 1537 1617 //////////////////////////////////////////////////////////////////////////////////////////////// 1538 1618 // Basic map filters API 1539 1619 -
binaries/data/mods/public/gui/gamesetup/gamesetup.xml
14 14 <object style="TitleText" type="text" size="50%-128 4 50%+128 36"> 15 15 Match Setup 16 16 </object> 17 17 18 18 <object type="image" style="ModernDialog" size="50%-190 50%-80 50%+190 50%+80" name="loadingWindow"> 19 19 20 20 <object type="text" style="TitleText" size="50%-128 0%-16 50%+128 16"> … … 32 32 <action on="Tick"> 33 33 onTick(); 34 34 </action> 35 35 36 36 <!-- Number of Players--> 37 37 <object size="24 26 224 54"> 38 38 … … 40 40 <object size="0 0 150 28"> 41 41 <object size="0 0 100% 100%" type="text" style="ModernRightLabelText">Number of players:</object> 42 42 </object> 43 43 44 44 <!-- Number of Players--> 45 45 <object size="150 0 200 28"> 46 46 <object name="numPlayersText" size="0 0 100% 100%" type="text" style="ModernLeftLabelText"/> … … 53 53 <action on="SelectionChange">selectNumPlayers(this.list_data[this.selected]);</action> 54 54 </object> 55 55 </object> 56 </object> 56 57 57 </object>58 59 58 <!-- Player assignments --> 60 59 <object size="24 59 100%-440 358" type="image" sprite="ModernDarkBoxGold" name="playerAssignmentsPannel"> 61 60 <object size="0 6 100% 30"> 62 <object name="playerNameHeading" type="text" style="ModernLabelText" size="0 0 20% 100%">Player Name</object> 63 <object name="playerPlacementHeading" type="text" style="ModernLabelText" size="20%+5 0 50% 100%">Player Placement</object> 64 <object name="playerCivHeading" type="text" style="ModernLabelText" size="50%+65 0 85% 100%">Civilization</object> 61 <object name="playerPlacementHeading" type="text" style="ModernLabelText" size="5 0 40% 100%">Player Name</object> 62 <object name="playerCivHeading" type="text" style="ModernLabelText" size="40%+65 0 75%-26 100%">Civilization</object> 65 63 <object name="civInfoButton" 66 64 type="button" 67 65 sprite="iconInfoGold" 68 66 sprite_over="iconInfoWhite" 69 size=" 82%-8 0 82%+816"67 size="57.5%+68 0 57.5%+84 16" 70 68 tooltip_style="onscreenToolTip" 71 69 tooltip="View civilization info" 72 70 > … … 74 72 Engine.PushGuiPage("page_civinfo.xml"); 75 73 ]]></action> 76 74 </object> 77 <object name="playerTeamHeading" type="text" style="ModernLabelText" size="85%+5 0 100%-5 100%">Team</object> 75 <object name="playerTeamHeading" type="text" style="ModernLabelText" size="75%+5 0 90%-5 100%">Team</object> 76 <object name="playerReadyHeading" type="text" style="ModernLabelText" size="90%+5 0 100%-5 100%">Ready</object> 78 77 </object> 79 78 <object size="1 36 100%-1 100%"> 80 79 <repeat count="8"> 81 80 <object name="playerBox[n]" size="0 0 100% 32" hidden="true"> 82 81 <object name="playerColour[n]" type="image" size="0 0 100% 100%"/> 83 <object name="playerName[n]" type="text" style="ModernLabelText" size="0 2 20% 30"/> 84 <object name="playerAssignment[n]" type="dropdown" style="ModernDropDown" size="20%+5 2 50% 30" tooltip_style="onscreenToolTip" tooltip="Select player."/> 85 <object name="playerConfig[n]" type="button" style="StoneButton" size="50%+5 6 50%+60 26" 82 <object name="playerAssignment[n]" type="dropdown" style="ModernDropDown" size="5 2 40% 30" tooltip_style="onscreenToolTip" tooltip="Select player."/> 83 <object name="playerConfig[n]" type="button" style="StoneButton" size="40%+5 6 40%+60 26" 86 84 tooltip_style="onscreenToolTip" 87 85 tooltip="Configure AI settings." 88 86 font="serif-bold-stroke-12" 89 87 >Settings</object> 90 <object name="playerCiv[n]" type="dropdown" style="ModernDropDown" size="50%+65 2 85% 30" tooltip_style="onscreenToolTip" tooltip="Select player's civilization."/> 91 <object name="playerCivText[n]" type="text" style="ModernLabelText" size="50%+65 0 85% 30"/> 92 <object name="playerTeam[n]" type="dropdown" style="ModernDropDown" size="85%+5 2 100%-5 30" tooltip_style="onscreenToolTip" tooltip="Select player's team."/> 93 <object name="playerTeamText[n]" type="text" style="ModernLabelText" size="85%+5 0 100%-5 100%"/> 88 <object name="playerCiv[n]" type="dropdown" style="ModernDropDown" size="40%+65 2 75% 30" tooltip_style="onscreenToolTip" tooltip="Select player's civilization."/> 89 <object name="playerCivText[n]" type="text" style="ModernLabelText" size="40%+65 0 75% 30"/> 90 <object name="playerTeam[n]" type="dropdown" style="ModernDropDown" size="75%+5 2 90%-5 30" tooltip_style="onscreenToolTip" tooltip="Select player's team."/> 91 <object name="playerTeamText[n]" type="text" style="ModernLabelText" size="75%+5 0 90%-5 100%"/> 92 <object name="playerReadySprite[n]" type="image" sprite="ModernCheckOff" size="95%-16 0 95%+16 32"/> 94 93 </object> 95 94 </repeat> 96 95 </object> 97 96 </object> 98 <object size="24 64 100%-460 358" type="image" sprite="CoverFillDark" name="playerAssignmentsPan nelCover" hidden="true"/>97 <object size="24 64 100%-460 358" type="image" sprite="CoverFillDark" name="playerAssignmentsPanelCover" hidden="true"/> 99 98 <!-- Map selection --> 100 99 101 100 … … 112 111 <object name="mapSelectionText" type="text" style="ModernLeftLabelText" size="0 64 100% 94" hidden="true"/> 113 112 <object name="mapSizeText" type="text" style="ModernLeftLabelText" size="0 96 100% 126" hidden="true"/> 114 113 </object> 115 114 116 115 <object name="mapTypeSelection" 117 116 type="dropdown" 118 117 style="ModernDropDown" … … 159 158 </object> 160 159 161 160 <!-- Chat window --> 162 <object name="chatPanel" size="24 370 100%-440 100%- 60" type="image" sprite="ModernDarkBoxGold">161 <object name="chatPanel" size="24 370 100%-440 100%-58" type="image" sprite="ModernDarkBoxGold"> 163 162 <object name="chatText" size="2 2 100%-2 100%-26" type="text" style="ChatPanel"/> 164 163 165 164 <object name="chatInput" size="4 100%-24 100%-76 100%-4" type="input" style="ModernInput"> … … 179 178 textcolor="white" 180 179 sprite="BackgroundTranslucent" 181 180 hidden="true" 182 size=" 100%-700 100%-56 100%-312100%-24"181 size="25 100%-56 100%-445 100%-24" 183 182 >[Tooltip text]</object> 184 183 184 <!-- Ready Button --> 185 <object 186 name="toggleReady" 187 type="button" 188 style="StoneButton" 189 hidden="false" 190 size="100%-425 100%-52 100%-305 100%-24" 191 tooltip_style="onscreenToolTip" 192 tooltip="Accept the current settings and state you are ready to play!" 193 enabled="true" 194 > 195 Set/Unset Ready 196 <action on="Press">toggleReady();</action> 197 </object> 198 185 199 <!-- Start Button --> 186 200 <object 187 201 name="startGame" 188 202 type="button" 189 203 style="StoneButton" 190 size="100%- 308 100%-52 100%-168100%-24"204 size="100%-285 100%-52 100%-165 100%-24" 191 205 tooltip_style="onscreenToolTip" 192 206 tooltip="Start a new game with the current settings." 193 207 enabled="false" … … 202 216 caption="Back" 203 217 type="button" 204 218 style="StoneButton" 205 size="100%-1 64 100%-52 100%-24100%-24"219 size="100%-145 100%-52 100%-25 100%-24" 206 220 tooltip_style="onscreenToolTip" 207 221 > 208 222 <action on="Press"> … … 215 229 ]]> 216 230 </action> 217 231 </object> 218 232 219 233 <!-- Options --> 220 234 <object name="gameOptionsBox" size="100%-425 497 100%-25 525"> 221 235 <!-- More Options Button --> -
source/gui/scripting/ScriptFunctions.cpp
343 343 g_NetServer->AssignPlayer(playerID, guid); 344 344 } 345 345 346 void AssignNetworkPlayerStatus(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int ready, std::string guid) 347 { 348 ENSURE(g_NetServer); 349 350 g_NetServer->ReadyPlayer(ready, guid); 351 } 352 353 void ClearAllPlayerReady (ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) 354 { 355 ENSURE(g_NetServer); 356 357 g_NetServer->ClearAllPlayerReady(); 358 } 359 346 360 void SendNetworkChat(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring message) 347 361 { 348 362 ENSURE(g_NetClient); … … 350 364 g_NetClient->SendChatMessage(message); 351 365 } 352 366 367 void SendNetworkReady(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int message) 368 { 369 ENSURE(g_NetClient); 370 371 g_NetClient->SendReadyMessage(message); 372 } 373 353 374 std::vector<CScriptValRooted> GetAIs(ScriptInterface::CxPrivate* pCxPrivate) 354 375 { 355 376 return ICmpAIManager::GetAIs(*(pCxPrivate->pScriptInterface)); … … 838 859 scriptInterface.RegisterFunction<CScriptVal, &PollNetworkClient>("PollNetworkClient"); 839 860 scriptInterface.RegisterFunction<void, CScriptVal, &SetNetworkGameAttributes>("SetNetworkGameAttributes"); 840 861 scriptInterface.RegisterFunction<void, int, std::string, &AssignNetworkPlayer>("AssignNetworkPlayer"); 862 scriptInterface.RegisterFunction<void, int, std::string, &AssignNetworkPlayerStatus>("AssignNetworkPlayerStatus"); 863 scriptInterface.RegisterFunction<void, &ClearAllPlayerReady>("ClearAllPlayerReady"); 841 864 scriptInterface.RegisterFunction<void, std::wstring, &SendNetworkChat>("SendNetworkChat"); 865 scriptInterface.RegisterFunction<void, int, &SendNetworkReady>("SendNetworkReady"); 842 866 scriptInterface.RegisterFunction<std::vector<CScriptValRooted>, &GetAIs>("GetAIs"); 843 867 scriptInterface.RegisterFunction<CScriptValRooted, &GetEngineInfo>("GetEngineInfo"); 844 868 -
source/network/NetClient.cpp
87 87 AddTransition(NCS_INITIAL_GAMESETUP, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context); 88 88 89 89 AddTransition(NCS_PREGAME, (uint)NMT_CHAT, NCS_PREGAME, (void*)&OnChat, context); 90 AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, (void*)&OnReady, context); 90 91 AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context); 91 92 AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, (void*)&OnPlayerAssignment, context); 92 93 AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, (void*)&OnGameStart, context); … … 214 215 GetScriptInterface().Eval("({})", host); 215 216 GetScriptInterface().SetProperty(host.get(), "name", std::wstring(it->second.m_Name), false); 216 217 GetScriptInterface().SetProperty(host.get(), "player", it->second.m_PlayerID, false); 218 GetScriptInterface().SetProperty(host.get(), "status", it->second.m_Status, false); 217 219 GetScriptInterface().SetProperty(hosts.get(), it->first.c_str(), host, false); 218 220 } 219 221 … … 254 256 SendMessage(&chat); 255 257 } 256 258 259 void CNetClient::SendReadyMessage(const int status) 260 { 261 CReadyMessage readyStatus; 262 readyStatus.m_Status = status; 263 SendMessage(&readyStatus); 264 } 265 257 266 bool CNetClient::HandleMessage(CNetMessage* message) 258 267 { 259 268 // Handle non-FSM messages first … … 419 428 return true; 420 429 } 421 430 431 bool CNetClient::OnReady(void* context, CFsmEvent* event) 432 { 433 ENSURE(event->GetType() == (uint)NMT_READY); 434 435 CNetClient* client = (CNetClient*)context; 436 437 CReadyMessage* message = (CReadyMessage*)event->GetParamRef(); 438 439 CScriptValRooted msg; 440 client->GetScriptInterface().Eval("({'type':'ready'})", msg); 441 client->GetScriptInterface().SetProperty(msg.get(), "guid", std::string(message->m_GUID), false); 442 client->GetScriptInterface().SetProperty(msg.get(), "text", int (message->m_Status), false); 443 client->PushGuiMessage(msg); 444 445 return true; 446 } 447 422 448 bool CNetClient::OnGameSetup(void* context, CFsmEvent* event) 423 449 { 424 450 ENSURE(event->GetType() == (uint)NMT_GAME_SETUP); … … 453 479 assignment.m_Enabled = true; 454 480 assignment.m_Name = message->m_Hosts[i].m_Name; 455 481 assignment.m_PlayerID = message->m_Hosts[i].m_PlayerID; 482 assignment.m_Status = message->m_Hosts[i].m_Status; 456 483 newPlayerAssignments[message->m_Hosts[i].m_GUID] = assignment; 457 484 } 458 485 -
source/network/NetClient.h
164 164 void LoadFinished(); 165 165 166 166 void SendChatMessage(const std::wstring& text); 167 168 void SendReadyMessage(const int status); 167 169 168 170 private: 169 171 // Net message / FSM transition handlers … … 172 174 static bool OnHandshakeResponse(void* context, CFsmEvent* event); 173 175 static bool OnAuthenticate(void* context, CFsmEvent* event); 174 176 static bool OnChat(void* context, CFsmEvent* event); 177 static bool OnReady(void* context, CFsmEvent* event); 175 178 static bool OnGameSetup(void* context, CFsmEvent* event); 176 179 static bool OnPlayerAssignment(void* context, CFsmEvent* event); 177 180 static bool OnInGame(void* context, CFsmEvent* event); -
source/network/NetHost.h
46 46 47 47 /// The player that the given host controls, or -1 if none (observer) 48 48 i32 m_PlayerID; 49 50 /// Status - Ready or not: 0 for not ready, 1 for ready 51 i32 m_Status; 49 52 }; 50 53 51 54 typedef std::map<CStr, PlayerAssignment> PlayerAssignmentMap; // map from GUID -> assignment -
source/network/NetMessage.cpp
174 174 case NMT_CHAT: 175 175 pNewMessage = new CChatMessage; 176 176 break; 177 178 case NMT_READY: 179 pNewMessage = new CReadyMessage; 180 break; 177 181 178 182 case NMT_SIMULATION_COMMAND: 179 183 pNewMessage = new CSimulationMessage(scriptInterface); -
source/network/NetMessages.h
46 46 NMT_AUTHENTICATE, // Authentication stage 47 47 NMT_AUTHENTICATE_RESULT, 48 48 NMT_CHAT, // Common chat message 49 NMT_READY, 49 50 NMT_GAME_SETUP, 50 51 NMT_PLAYER_ASSIGNMENT, 51 52 … … 118 119 NMT_FIELD(CStrW, m_Message) 119 120 END_NMT_CLASS() 120 121 122 START_NMT_CLASS_(Ready, NMT_READY) 123 NMT_FIELD(CStr8, m_GUID) 124 NMT_FIELD_INT(m_Status, u8, 1) 125 END_NMT_CLASS() 126 121 127 START_NMT_CLASS_(PlayerAssignment, NMT_PLAYER_ASSIGNMENT) 122 128 NMT_START_ARRAY(m_Hosts) 123 129 NMT_FIELD(CStr8, m_GUID) 124 130 NMT_FIELD(CStrW, m_Name) 125 131 NMT_FIELD_INT(m_PlayerID, i8, 1) 132 NMT_FIELD_INT(m_Status, u8, 1) 126 133 NMT_END_ARRAY() 127 134 END_NMT_CLASS() 128 135 -
source/network/NetServer.cpp
376 376 377 377 std::vector<std::pair<int, CStr> > newAssignPlayer; 378 378 std::vector<bool> newStartGame; 379 std::vector<std::pair<int, CStr> > newPlayerReady; 380 std::vector<bool> newPlayerResetReady; 379 381 std::vector<std::string> newGameAttributes; 380 382 std::vector<u32> newTurnLength; 381 383 … … 386 388 return false; 387 389 388 390 newStartGame.swap(m_StartGameQueue); 391 newPlayerReady.swap(m_PlayerReadyQueue); 392 newPlayerResetReady.swap(m_PlayerResetReadyQueue); 389 393 newAssignPlayer.swap(m_AssignPlayerQueue); 390 394 newGameAttributes.swap(m_GameAttributesQueue); 391 395 newTurnLength.swap(m_TurnLengthQueue); … … 394 398 for (size_t i = 0; i < newAssignPlayer.size(); ++i) 395 399 AssignPlayer(newAssignPlayer[i].first, newAssignPlayer[i].second); 396 400 401 for (size_t i = 0; i < newPlayerReady.size(); ++i) 402 ReadyPlayer(newPlayerReady[i].first, newPlayerReady[i].second); 403 404 if (!newPlayerResetReady.empty()) 405 ClearAllPlayerReady(); 406 397 407 if (!newGameAttributes.empty()) 398 408 UpdateGameAttributes(GetScriptInterface().ParseJSON(newGameAttributes.back())); 399 409 … … 548 558 549 559 session->AddTransition(NSS_PREGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context); 550 560 session->AddTransition(NSS_PREGAME, (uint)NMT_CHAT, NSS_PREGAME, (void*)&OnChat, context); 561 session->AddTransition(NSS_PREGAME, (uint)NMT_READY, NSS_PREGAME, (void*)&OnReady, context); 551 562 session->AddTransition(NSS_PREGAME, (uint)NMT_LOADED_GAME, NSS_INGAME, (void*)&OnLoadedGame, context); 552 563 553 564 session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NSS_INGAME, (void*)&OnJoinSyncingLoadedGame, context); … … 649 660 assignment.m_Enabled = true; 650 661 assignment.m_Name = name; 651 662 assignment.m_PlayerID = playerID; 663 assignment.m_Status = 0; 652 664 m_PlayerAssignments[guid] = assignment; 653 665 654 666 // Send the new assignments to all currently active players … … 663 675 SendPlayerAssignments(); 664 676 } 665 677 678 void CNetServerWorker::ReadyPlayer(const int ready, const CStr& guid) 679 { 680 m_PlayerAssignments[guid].m_Status = ready; 681 682 SendPlayerAssignments(); 683 } 684 685 void CNetServerWorker::ClearAllPlayerReady() 686 { 687 for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it) 688 { 689 it->second.m_Status = 0; 690 } 691 692 SendPlayerAssignments(); 693 } 694 666 695 void CNetServerWorker::AssignPlayer(int playerID, const CStr& guid) 667 696 { 668 697 // Remove anyone who's already assigned to this player … … 690 719 h.m_GUID = it->first; 691 720 h.m_Name = it->second.m_Name; 692 721 h.m_PlayerID = it->second.m_PlayerID; 722 h.m_Status = it->second.m_Status; 693 723 message.m_Hosts.push_back(h); 694 724 } 695 725 } … … 860 890 return true; 861 891 } 862 892 893 bool CNetServerWorker::OnReady(void* context, CFsmEvent* event) 894 { 895 ENSURE(event->GetType() == (uint)NMT_READY); 896 897 CNetServerSession* session = (CNetServerSession*)context; 898 CNetServerWorker& server = session->GetServer(); 899 900 CReadyMessage* message = (CReadyMessage*)event->GetParamRef(); 901 902 message->m_GUID = session->GetGUID(); 903 904 server.Broadcast(message); 905 906 return true; 907 } 908 863 909 bool CNetServerWorker::OnLoadedGame(void* context, CFsmEvent* event) 864 910 { 865 911 ENSURE(event->GetType() == (uint)NMT_LOADED_GAME); … … 1053 1099 m_Worker->m_AssignPlayerQueue.push_back(std::make_pair(playerID, guid)); 1054 1100 } 1055 1101 1102 void CNetServer::ReadyPlayer(int ready, const CStr& guid) 1103 { 1104 CScopeLock lock(m_Worker->m_WorkerMutex); 1105 m_Worker->m_PlayerReadyQueue.push_back(std::make_pair(ready, guid)); 1106 } 1107 1108 void CNetServer::ClearAllPlayerReady() 1109 { 1110 CScopeLock lock(m_Worker->m_WorkerMutex); 1111 m_Worker->m_PlayerResetReadyQueue.push_back(false); 1112 } 1113 1056 1114 void CNetServer::StartGame() 1057 1115 { 1058 1116 CScopeLock lock(m_Worker->m_WorkerMutex); -
source/network/NetServer.h
122 122 * The changes will be asynchronously propagated to all clients. 123 123 */ 124 124 void AssignPlayer(int playerID, const CStr& guid); 125 126 /** 127 * Call from the GUI to update the player readiness. 128 * The changes will be asynchronously propagated to all clients. 129 */ 130 void ReadyPlayer(int ready, const CStr& guid); 125 131 126 132 /** 133 * Call from the GUI to set the all player readiness to 0. 134 * The changes will be asynchronously propagated to all clients. 135 */ 136 void ClearAllPlayerReady(); 137 138 /** 127 139 * Call from the GUI to asynchronously notify all clients that they should start loading the game. 128 140 */ 129 141 void StartGame(); … … 233 245 234 246 void AddPlayer(const CStr& guid, const CStrW& name); 235 247 void RemovePlayer(const CStr& guid); 248 void ReadyPlayer(const int ready, const CStr& guid); 236 249 void SendPlayerAssignments(); 250 void ClearAllPlayerReady(); 237 251 238 252 void SetupSession(CNetServerSession* session); 239 253 bool HandleConnect(CNetServerSession* session); … … 245 259 static bool OnAuthenticate(void* context, CFsmEvent* event); 246 260 static bool OnInGame(void* context, CFsmEvent* event); 247 261 static bool OnChat(void* context, CFsmEvent* event); 262 static bool OnReady(void* context, CFsmEvent* event); 248 263 static bool OnLoadedGame(void* context, CFsmEvent* event); 249 264 static bool OnJoinSyncingLoadedGame(void* context, CFsmEvent* event); 250 265 static bool OnDisconnect(void* context, CFsmEvent* event); … … 320 335 // Queues for messages sent by the game thread: 321 336 std::vector<std::pair<int, CStr> > m_AssignPlayerQueue; // protected by m_WorkerMutex 322 337 std::vector<bool> m_StartGameQueue; // protected by m_WorkerMutex 338 std::vector<std::pair<int, CStr> > m_PlayerReadyQueue; // protected by m_WorkerMutex 339 std::vector<bool> m_PlayerResetReadyQueue; // protected by m_WorkerMutex 323 340 std::vector<std::string> m_GameAttributesQueue; // protected by m_WorkerMutex 324 341 std::vector<u32> m_TurnLengthQueue; // protected by m_WorkerMutex 325 342 };