Fix GUI issues when reconnecting to multiplayer games

This was SVN commit r10452.
This commit is contained in:
Ykkrosh 2011-10-29 14:53:13 +00:00
parent 0a676171a5
commit b454ccca79
7 changed files with 136 additions and 50 deletions

View File

@ -1,6 +1,10 @@
var g_IsConnecting = false; var g_IsConnecting = false;
var g_GameType; // "server" or "client" var g_GameType; // "server" or "client"
var g_IsRejoining = false;
var g_GameAttributes; // used when rejoining
var g_PlayerAssignments; // used when rejoining
function init(multiplayerGameType) function init(multiplayerGameType)
{ {
switch (multiplayerGameType) switch (multiplayerGameType)
@ -30,6 +34,7 @@ function startConnectionStatus(type)
{ {
g_GameType = type; g_GameType = type;
g_IsConnecting = true; g_IsConnecting = true;
g_IsRejoining = false;
getGUIObjectByName("connectionStatus").caption = "Connecting to server..."; getGUIObjectByName("connectionStatus").caption = "Connecting to server...";
} }
@ -46,6 +51,55 @@ function onTick()
log("Net message: "+uneval(message)); log("Net message: "+uneval(message));
// If we're rejoining an active game, we don't want to actually display
// the game setup screen, so perform similar processing to gamesetup.js
// in this screen
if (g_IsRejoining)
{
switch (message.type)
{
case "netstatus":
switch (message.status)
{
case "disconnected":
cancelSetup();
reportDisconnect(message.reason);
return;
default:
error("Unrecognised netstatus type "+message.status);
break;
}
break;
case "gamesetup":
g_GameAttributes = message.data;
break;
case "players":
g_PlayerAssignments = message.hosts;
break;
case "start":
Engine.SwitchGuiPage("page_loading.xml", {
"attribs": g_GameAttributes,
"isNetworked" : true,
"playerAssignments": g_PlayerAssignments
});
break;
case "chat":
// Ignore, since we have nowhere to display chat messages
break;
default:
error("Unrecognised net message type "+message.type);
}
}
else
{
// Not rejoining - just trying to connect to server
switch (message.type) switch (message.type)
{ {
case "netstatus": case "netstatus":
@ -56,9 +110,18 @@ function onTick()
break; break;
case "authenticated": case "authenticated":
if (message.rejoining)
{
getGUIObjectByName("connectionStatus").caption = "Game has already started - rejoining...";
g_IsRejoining = true;
return; // we'll process the game setup messages in the next tick
}
else
{
Engine.PopGuiPage(); Engine.PopGuiPage();
Engine.PushGuiPage("page_gamesetup.xml", { "type": g_GameType }); Engine.PushGuiPage("page_gamesetup.xml", { "type": g_GameType });
return; // don't process any more messages - leave them for the game GUI loop return; // don't process any more messages - leave them for the game GUI loop
}
case "disconnected": case "disconnected":
cancelSetup(); cancelSetup();
@ -75,6 +138,7 @@ function onTick()
break; break;
} }
} }
}
} }
function switchSetupPage(oldpage, newpage) function switchSetupPage(oldpage, newpage)

View File

@ -74,6 +74,10 @@ function handleNetMessage(message)
obj.caption = "Waiting for other players to connect..."; obj.caption = "Waiting for other players to connect...";
obj.hidden = false; obj.hidden = false;
break; break;
case "join_syncing":
obj.caption = "Synchronising gameplay with other players...";
obj.hidden = false;
break;
case "active": case "active":
obj.caption = ""; obj.caption = "";
obj.hidden = true; obj.hidden = true;
@ -116,6 +120,9 @@ function handleNetMessage(message)
{ {
// Update the cached player data, so we can display the correct name // Update the cached player data, so we can display the correct name
updatePlayerDataAdd(g_Players, host, message.hosts[host]); updatePlayerDataAdd(g_Players, host, message.hosts[host]);
// Tell the user about the connection
addChatMessage({ "type": "connect", "guid": host }, message.hosts);
} }
} }
@ -167,14 +174,19 @@ function submitChatInput()
toggleChatWindow(); toggleChatWindow();
} }
function addChatMessage(msg) function addChatMessage(msg, playerAssignments)
{ {
// Default to global assignments, but allow overriding for when reporting
// new players joining
if (!playerAssignments)
playerAssignments = g_PlayerAssignments;
var playerColor, username; var playerColor, username;
if (g_PlayerAssignments[msg.guid]) if (playerAssignments[msg.guid])
{ {
var n = g_PlayerAssignments[msg.guid].player; var n = playerAssignments[msg.guid].player;
playerColor = g_Players[n].color.r + " " + g_Players[n].color.g + " " + g_Players[n].color.b; playerColor = g_Players[n].color.r + " " + g_Players[n].color.g + " " + g_Players[n].color.b;
username = escapeText(g_PlayerAssignments[msg.guid].name); username = escapeText(playerAssignments[msg.guid].name);
} }
else else
{ {
@ -188,6 +200,9 @@ function addChatMessage(msg)
switch (msg.type) switch (msg.type)
{ {
case "connect":
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has joined the game.";
break;
case "disconnect": case "disconnect":
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has left the game."; formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has left the game.";
break; break;

View File

@ -71,6 +71,7 @@ function updatePlayerDataAdd(players, hostGuid, playerAssignment)
{ {
players[playerAssignment.player].guid = hostGuid; players[playerAssignment.player].guid = hostGuid;
players[playerAssignment.player].name = playerAssignment.name; players[playerAssignment.player].name = playerAssignment.name;
players[playerAssignment.player].offline = false;
} }
} }

View File

@ -294,6 +294,9 @@ void CNetClient::LoadFinished()
{ {
if (!m_JoinSyncBuffer.empty()) if (!m_JoinSyncBuffer.empty())
{ {
// We're rejoining a game, and just finished loading the initial map,
// so deserialize the saved game state now
std::string state; std::string state;
DecompressZLib(m_JoinSyncBuffer, state, true); DecompressZLib(m_JoinSyncBuffer, state, true);
@ -309,11 +312,18 @@ void CNetClient::LoadFinished()
ENSURE(ok); ENSURE(ok);
m_ClientTurnManager->ResetState(turn, turn); m_ClientTurnManager->ResetState(turn, turn);
}
CScriptValRooted msg;
GetScriptInterface().Eval("({'type':'netstatus','status':'join_syncing'})", msg);
PushGuiMessage(msg);
}
else
{
// Connecting at the start of a game, so we'll wait for other players to finish loading
CScriptValRooted msg; CScriptValRooted msg;
GetScriptInterface().Eval("({'type':'netstatus','status':'waiting_for_players'})", msg); GetScriptInterface().Eval("({'type':'netstatus','status':'waiting_for_players'})", msg);
PushGuiMessage(msg); PushGuiMessage(msg);
}
CLoadedGameMessage loaded; CLoadedGameMessage loaded;
loaded.m_CurrentTurn = m_ClientTurnManager->GetCurrentTurn(); loaded.m_CurrentTurn = m_ClientTurnManager->GetCurrentTurn();
@ -371,12 +381,15 @@ bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event)
CAuthenticateResultMessage* message = (CAuthenticateResultMessage*)event->GetParamRef(); CAuthenticateResultMessage* message = (CAuthenticateResultMessage*)event->GetParamRef();
LOGMESSAGE(L"Net: Authentication result: host=%d, %ls", message->m_HostID, message->m_Message.c_str() ); LOGMESSAGE(L"Net: Authentication result: host=%d, %ls", message->m_HostID, message->m_Message.c_str());
bool isRejoining = (message->m_Code == ARC_OK_REJOINING);
client->m_HostID = message->m_HostID; client->m_HostID = message->m_HostID;
CScriptValRooted msg; CScriptValRooted msg;
client->GetScriptInterface().Eval("({'type':'netstatus','status':'authenticated'})", msg); client->GetScriptInterface().Eval("({'type':'netstatus','status':'authenticated'})", msg);
client->GetScriptInterface().SetProperty(msg.get(), "rejoining", isRejoining);
client->PushGuiMessage(msg); client->PushGuiMessage(msg);
return true; return true;

View File

@ -69,9 +69,8 @@ enum NetMessageType
enum AuthenticateResultCode enum AuthenticateResultCode
{ {
ARC_OK, ARC_OK,
ARC_OK_REJOINING,
ARC_PASSWORD_INVALID, ARC_PASSWORD_INVALID,
ARC_NICK_TAKEN,
ARC_NICK_INVALID,
}; };
#endif // NETMESSAGES_H #endif // NETMESSAGES_H

View File

@ -665,7 +665,7 @@ bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event)
session->SetHostID(newHostID); session->SetHostID(newHostID);
CAuthenticateResultMessage authenticateResult; CAuthenticateResultMessage authenticateResult;
authenticateResult.m_Code = ARC_OK; authenticateResult.m_Code = isRejoining ? ARC_OK_REJOINING : ARC_OK;
authenticateResult.m_HostID = newHostID; authenticateResult.m_HostID = newHostID;
authenticateResult.m_Message = L"Logged in"; authenticateResult.m_Message = L"Logged in";
session->SendMessage(&authenticateResult); session->SendMessage(&authenticateResult);

View File

@ -65,12 +65,6 @@ class CGame
CNetTurnManager* m_TurnManager; CNetTurnManager* m_TurnManager;
public: public:
enum ENetStatus
{
NET_WAITING_FOR_CONNECT, /// we have loaded the game; waiting for other players to finish loading
NET_NORMAL /// running the game
};
CGame(bool disableGraphics = false); CGame(bool disableGraphics = false);
~CGame(); ~CGame();