Index: binaries/data/mods/public/gui/session/messages.js
===================================================================
--- binaries/data/mods/public/gui/session/messages.js
+++ binaries/data/mods/public/gui/session/messages.js
@@ -45,6 +45,9 @@
"paused": msg => {
setClientPauseState(msg.guid, msg.pause);
},
+ "clients-waiting-for": msg => {
+ handleClientsWaitingForMessage(msg.guids);
+ },
"rejoined": msg => {
addChatMessage({
"type": "rejoined",
@@ -134,7 +137,7 @@
sprintf(translate("Reason: %(reason)s."), {
"reason": getDisconnectReason(msg.reason, true)
}),
- "waiting_for_players": msg => translate("Waiting for other players to connect..."),
+ "waiting_for_players": msg => translate("Waiting for players to connect:"),
"join_syncing": msg => translate("Synchronising gameplay with other players..."),
"active": msg => ""
};
@@ -583,11 +586,14 @@
g_IsNetworkedActive = message.status == "active";
- let label = Engine.GetGUIObjectByName("netStatus");
+ let netStatus = Engine.GetGUIObjectByName("netStatus");
let statusMessage = g_StatusMessageTypes[message.status](message);
- label.caption = statusMessage;
- label.hidden = !statusMessage;
+ netStatus.caption = statusMessage;
+ netStatus.hidden = !statusMessage;
+ let netStatusText = Engine.GetGUIObjectByName("netStatusText");
+ netStatusText.hidden = message.status != "waiting_for_players";
+
if (message.status == "disconnected")
{
// Hide the pause overlay, and pause animations.
@@ -599,6 +605,12 @@
}
}
+function handleClientsWaitingForMessage(guids)
+{
+ let netStatusText = Engine.GetGUIObjectByName("netStatusText");
+ netStatusText.caption = guids.map(guid => colorizePlayernameByGUID(guid)).join(translate(", "));
+}
+
function handlePlayerAssignmentsMessage(message)
{
for (let guid in g_PlayerAssignments)
Index: binaries/data/mods/public/gui/session/session.xml
===================================================================
--- binaries/data/mods/public/gui/session/session.xml
+++ binaries/data/mods/public/gui/session/session.xml
@@ -159,6 +159,7 @@
leaveGame();
+
Index: source/network/NetClient.h
===================================================================
--- source/network/NetClient.h
+++ source/network/NetClient.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -233,6 +233,7 @@
static bool OnKicked(void* context, CFsmEvent* event);
static bool OnClientTimeout(void* context, CFsmEvent* event);
static bool OnClientPerformance(void* context, CFsmEvent* event);
+ static bool OnClientsWaitingFor(void* context, CFsmEvent* event);
static bool OnClientPaused(void* context, CFsmEvent* event);
static bool OnLoadedGame(void* context, CFsmEvent* event);
Index: source/network/NetClient.cpp
===================================================================
--- source/network/NetClient.cpp
+++ source/network/NetClient.cpp
@@ -119,6 +119,7 @@
AddTransition(NCS_LOADING, (uint)NMT_KICKED, NCS_LOADING, (void*)&OnKicked, context);
AddTransition(NCS_LOADING, (uint)NMT_CLIENT_TIMEOUT, NCS_LOADING, (void*)&OnClientTimeout, context);
AddTransition(NCS_LOADING, (uint)NMT_CLIENT_PERFORMANCE, NCS_LOADING, (void*)&OnClientPerformance, context);
+ AddTransition(NCS_LOADING, (uint)NMT_CLIENTS_WAITING_FOR, NCS_LOADING, (void*)&OnClientsWaitingFor, context);
AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context);
AddTransition(NCS_INGAME, (uint)NMT_REJOINED, NCS_INGAME, (void*)&OnRejoined, context);
@@ -125,6 +126,7 @@
AddTransition(NCS_INGAME, (uint)NMT_KICKED, NCS_INGAME, (void*)&OnKicked, context);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_INGAME, (void*)&OnClientTimeout, context);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_INGAME, (void*)&OnClientPerformance, context);
+ AddTransition(NCS_INGAME, (uint)NMT_CLIENTS_WAITING_FOR, NCS_INGAME, (void*)&OnClientsWaitingFor, context);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PAUSED, NCS_INGAME, (void*)&OnClientPaused, context);
AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, (void*)&OnChat, context);
AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, (void*)&OnGameSetup, context);
@@ -778,6 +780,27 @@
return true;
}
+bool CNetClient::OnClientsWaitingFor(void *context, CFsmEvent *event)
+{
+ ENSURE(event->GetType() == (uint)NMT_CLIENTS_WAITING_FOR);
+
+ CClientsWaitingForMessage* message = (CClientsWaitingForMessage*)event->GetParamRef();
+
+ std::vector guids;
+ for (size_t i = 0; i < message->m_Clients.size(); ++i)
+ guids.push_back(message->m_Clients[i].m_GUID);
+
+ CNetClient* client = (CNetClient*)context;
+ JSContext* cx = client->GetScriptInterface().GetContext();
+ JSAutoRequest rq(cx);
+
+ JS::RootedValue msg(cx);
+ client->GetScriptInterface().Eval("({ 'type':'clients-waiting-for' })", &msg);
+ client->GetScriptInterface().SetProperty(msg, "guids", guids);
+ client->PushGuiMessage(msg);
+ return true;
+}
+
bool CNetClient::OnClientPaused(void *context, CFsmEvent *event)
{
ENSURE(event->GetType() == (uint)NMT_CLIENT_PAUSED);
Index: source/network/NetMessage.cpp
===================================================================
--- source/network/NetMessage.cpp
+++ source/network/NetMessage.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -147,6 +147,10 @@
pNewMessage = new CClientPerformanceMessage;
break;
+ case NMT_CLIENTS_WAITING_FOR:
+ pNewMessage = new CClientsWaitingForMessage;
+ break;
+
case NMT_CLIENT_PAUSED:
pNewMessage = new CClientPausedMessage;
break;
Index: source/network/NetMessages.h
===================================================================
--- source/network/NetMessages.h
+++ source/network/NetMessages.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -28,7 +28,7 @@
#define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?'
#define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!'
-#define PS_PROTOCOL_VERSION 0x01010014 // Arbitrary protocol
+#define PS_PROTOCOL_VERSION 0x01010015 // Arbitrary protocol
#define PS_DEFAULT_PORT 0x5073 // 'P', 's'
// Defines the list of message types. The order of the list must not change.
@@ -67,6 +67,7 @@
NMT_CLIENT_TIMEOUT,
NMT_CLIENT_PERFORMANCE,
+ NMT_CLIENTS_WAITING_FOR,
NMT_CLIENT_PAUSED,
NMT_LOADED_GAME,
@@ -193,6 +194,12 @@
NMT_END_ARRAY()
END_NMT_CLASS()
+START_NMT_CLASS_(ClientsWaitingFor, NMT_CLIENTS_WAITING_FOR)
+ NMT_START_ARRAY(m_Clients)
+ NMT_FIELD(CStr, m_GUID)
+ NMT_END_ARRAY()
+END_NMT_CLASS()
+
START_NMT_CLASS_(ClientPaused, NMT_CLIENT_PAUSED)
NMT_FIELD(CStr, m_GUID)
NMT_FIELD_INT(m_Pause, u8, 1)
Index: source/network/NetServer.cpp
===================================================================
--- source/network/NetServer.cpp
+++ source/network/NetServer.cpp
@@ -1166,13 +1166,24 @@
{
ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);
- CNetServerSession* session = (CNetServerSession*)context;
- CNetServerWorker& server = session->GetServer();
+ CNetServerSession* loadedSession = (CNetServerSession*)context;
+ CNetServerWorker& server = loadedSession->GetServer();
+ CClientsWaitingForMessage message;
+ for (CNetServerSession* session : server.m_Sessions)
+ if (session->GetCurrState() != NSS_INGAME && loadedSession->GetGUID() != session->GetGUID())
+ {
+ CClientsWaitingForMessage::S_m_Clients client;
+ client.m_GUID = session->GetGUID();
+ message.m_Clients.push_back(client);
+ }
+ // Send to the loaded player
+ loadedSession->SendMessage(&message);
+ server.Broadcast(&message, { NSS_INGAME });
// We're in the loading state, so wait until every player has loaded before
// starting the game
ENSURE(server.m_State == SERVER_STATE_LOADING);
- server.CheckGameLoadStatus(session);
+ server.CheckGameLoadStatus(loadedSession);
return true;
}