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,22 +1,26 @@
var g_IsConnecting = false;
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)
{
switch (multiplayerGameType)
{
case "join":
getGUIObjectByName("pageJoin").hidden = false;
getGUIObjectByName("pageHost").hidden = true;
break;
case "host":
getGUIObjectByName("pageJoin").hidden = true;
getGUIObjectByName("pageHost").hidden = false;
break;
default:
error("Unrecognised multiplayer game type : " + multiplayerGameType);
break;
}
switch (multiplayerGameType)
{
case "join":
getGUIObjectByName("pageJoin").hidden = false;
getGUIObjectByName("pageHost").hidden = true;
break;
case "host":
getGUIObjectByName("pageJoin").hidden = true;
getGUIObjectByName("pageHost").hidden = false;
break;
default:
error("Unrecognised multiplayer game type : " + multiplayerGameType);
break;
}
}
function cancelSetup()
@ -30,6 +34,7 @@ function startConnectionStatus(type)
{
g_GameType = type;
g_IsConnecting = true;
g_IsRejoining = false;
getGUIObjectByName("connectionStatus").caption = "Connecting to server...";
}
@ -46,33 +51,92 @@ function onTick()
log("Net message: "+uneval(message));
switch (message.type)
// 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)
{
case "netstatus":
switch (message.status)
switch (message.type)
{
case "connected":
getGUIObjectByName("connectionStatus").caption = "Registering with server...";
case "netstatus":
switch (message.status)
{
case "disconnected":
cancelSetup();
reportDisconnect(message.reason);
return;
default:
error("Unrecognised netstatus type "+message.status);
break;
}
break;
case "authenticated":
Engine.PopGuiPage();
Engine.PushGuiPage("page_gamesetup.xml", { "type": g_GameType });
return; // don't process any more messages - leave them for the game GUI loop
case "gamesetup":
g_GameAttributes = message.data;
break;
case "disconnected":
cancelSetup();
reportDisconnect(message.reason);
return;
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 netstatus type "+message.status);
error("Unrecognised net message type "+message.type);
}
}
else
{
// Not rejoining - just trying to connect to server
switch (message.type)
{
case "netstatus":
switch (message.status)
{
case "connected":
getGUIObjectByName("connectionStatus").caption = "Registering with server...";
break;
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.PushGuiPage("page_gamesetup.xml", { "type": g_GameType });
return; // don't process any more messages - leave them for the game GUI loop
}
case "disconnected":
cancelSetup();
reportDisconnect(message.reason);
return;
default:
error("Unrecognised netstatus type "+message.status);
break;
}
break;
default:
error("Unrecognised net message type "+message.type);
break;
}
break;
default:
error("Unrecognised net message type "+message.type);
break;
}
}
}

View File

@ -74,6 +74,10 @@ function handleNetMessage(message)
obj.caption = "Waiting for other players to connect...";
obj.hidden = false;
break;
case "join_syncing":
obj.caption = "Synchronising gameplay with other players...";
obj.hidden = false;
break;
case "active":
obj.caption = "";
obj.hidden = true;
@ -116,6 +120,9 @@ function handleNetMessage(message)
{
// Update the cached player data, so we can display the correct name
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();
}
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;
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;
username = escapeText(g_PlayerAssignments[msg.guid].name);
username = escapeText(playerAssignments[msg.guid].name);
}
else
{
@ -188,6 +200,9 @@ function addChatMessage(msg)
switch (msg.type)
{
case "connect":
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has joined the game.";
break;
case "disconnect":
formatted = "[color=\"" + playerColor + "\"]" + username + "[/color] has left the game.";
break;

View File

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

View File

@ -294,6 +294,9 @@ void CNetClient::LoadFinished()
{
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;
DecompressZLib(m_JoinSyncBuffer, state, true);
@ -309,11 +312,18 @@ void CNetClient::LoadFinished()
ENSURE(ok);
m_ClientTurnManager->ResetState(turn, turn);
}
CScriptValRooted msg;
GetScriptInterface().Eval("({'type':'netstatus','status':'waiting_for_players'})", msg);
PushGuiMessage(msg);
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;
GetScriptInterface().Eval("({'type':'netstatus','status':'waiting_for_players'})", msg);
PushGuiMessage(msg);
}
CLoadedGameMessage loaded;
loaded.m_CurrentTurn = m_ClientTurnManager->GetCurrentTurn();
@ -371,12 +381,15 @@ bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event)
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;
CScriptValRooted msg;
client->GetScriptInterface().Eval("({'type':'netstatus','status':'authenticated'})", msg);
client->GetScriptInterface().SetProperty(msg.get(), "rejoining", isRejoining);
client->PushGuiMessage(msg);
return true;

View File

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

View File

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

View File

@ -65,12 +65,6 @@ class CGame
CNetTurnManager* m_TurnManager;
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();