1
0
forked from 0ad/0ad

Translate the Out-Of-Sync error message and send it to the JS GUI for convenience and future extension.

Add a hint that multiplayer games with AI are currently not supported.

Differential Revision: https://code.wildfiregames.com/D105
Reviewed By: leper
Refs #3858

This was SVN commit r19491.
This commit is contained in:
elexis 2017-05-01 04:55:56 +00:00
parent 7d6bfe27ab
commit 37da3b008a
5 changed files with 85 additions and 26 deletions

View File

@ -44,6 +44,9 @@ var g_NetMessageTypes = {
"netwarn": msg => {
addNetworkWarning(msg);
},
"out-of-sync": msg => {
onNetworkOutOfSync(msg);
},
"players": msg => {
handlePlayerAssignmentsMessage(msg);
},
@ -623,6 +626,58 @@ function handleClientsLoadingMessage(guids)
loadingClientsText.caption = guids.map(guid => colorizePlayernameByGUID(guid)).join(translate(", "));
}
function onNetworkOutOfSync(msg)
{
let txt = [
sprintf(translate("Out-Of-Sync error on turn %(turn)s."), {
"turn": msg.turn
}),
sprintf(translateWithContext("Out-Of-Sync", "Players: %(players)s"), {
"players": msg.players.join(translate(", "))
}),
msg.hash == msg.expectedHash ?
translateWithContext("Out-Of-Sync", "Your game state is identical to the hosts game state.") :
translateWithContext("Out-Of-Sync", "Your game state differs from the hosts game state."),
""
];
if (msg.turn > 1 && g_GameAttributes.settings.PlayerData.some(pData => pData && pData.AI))
txt.push(translateWithContext("Out-Of-Sync", "Rejoining Multiplayer games with AIs is not supported yet!"));
else
{
txt.push(
translateWithContext("Out-Of-Sync", "Ensure all players use the same mods."),
translateWithContext("Out-Of-Sync", 'Click on "Report Bugs" in the main menu to help fix this.'),
sprintf(translateWithContext("Out-Of-Sync", "Replay saved to %(filepath)s"), {
"filepath": escapeText(msg.path_replay)
}),
sprintf(translateWithContext("Out-Of-Sync", "Dumping current state to %(filepath)s"), {
"filepath": escapeText(msg.path_oos_dump)
})
);
}
messageBox(
600, 280,
txt.join("\n"),
translate("Out of Sync")
);
}
function onReplayOutOfSync()
{
messageBox(
500, 140,
translate("Out-Of-Sync error!") + "\n" +
// Translation: This is shown if replay is out of sync
translateWithContext("Out-Of-Sync", "The current game state is different from the original game state."),
translate("Out Of Sync")
);
}
function handlePlayerAssignmentsMessage(message)
{
for (let guid in g_PlayerAssignments)

View File

@ -30,6 +30,10 @@
onReplayFinished();
</action>
<action on="ReplayOutOfSync">
onReplayOutOfSync();
</action>
<action on="Press">
this.hidden = !this.hidden;
</action>

View File

@ -122,18 +122,29 @@ void CNetClientTurnManager::OnSyncError(u32 turn, const CStr& expectedHash, cons
hash = Hexify(hash);
std::stringstream msg;
msg << "Out of sync on turn " << turn;
std::stringstream playerNamesString;
std::vector<CStr> playerNamesStrings;
playerNamesStrings.reserve(playerNames.size());
for (size_t i = 0; i < playerNames.size(); ++i)
msg << (i == 0 ? "\nPlayers: " : ", ") << utf8_from_wstring(playerNames[i].m_Name);
{
CStr name = utf8_from_wstring(playerNames[i].m_Name);
playerNamesString << (i == 0 ? "" : ", ") << name;
playerNamesStrings.push_back(name);
}
msg << "\n\n" << "Your game state is " << (expectedHash == hash ? "identical to" : "different from") << " the hosts game state.";
LOGERROR("Out-Of-Sync on turn %d\nPlayers: %s\nDumping state to %s", turn, playerNamesString.str().c_str(), path.string8());
msg << "\n\n" << "Dumping current state to " << CStr(path.string8()).EscapeToPrintableASCII();
ScriptInterface& scriptInterface = m_NetClient.GetScriptInterface();
JSContext* cx = scriptInterface.GetContext();
JSAutoRequest rq(cx);
LOGERROR("%s", msg.str());
if (g_GUI)
g_GUI->DisplayMessageBox(600, 350, L"Sync error", wstring_from_utf8(msg.str()));
JS::RootedValue msg(cx);
scriptInterface.Eval("({ 'type':'out-of-sync' })", &msg);
scriptInterface.SetProperty(msg, "turn", turn);
scriptInterface.SetProperty(msg, "players", playerNamesStrings);
scriptInterface.SetProperty(msg, "expectedHash", expectedHash);
scriptInterface.SetProperty(msg, "hash", hash);
scriptInterface.SetProperty(msg, "path_oos_dump", path.string8());
scriptInterface.SetProperty(msg, "path_replay", m_Replay.GetDirectory().string8());
m_NetClient.PushGuiMessage(msg);
}

View File

@ -77,7 +77,11 @@ void CReplayTurnManager::NotifyFinishedUpdate(u32 turn)
hash = Hexify(hash);
if (hash != expectedHash)
OnSyncError(turn);
{
m_HasSyncError = true;
LOGERROR("Replay out of sync on turn %d", turn);
g_GUI->SendEventToAll("ReplayOutOfSync");
}
}
void CReplayTurnManager::DoTurn(u32 turn)
@ -100,16 +104,3 @@ void CReplayTurnManager::DoTurn(u32 turn)
if (turn == m_FinalTurn)
g_GUI->SendEventToAll("ReplayFinished");
}
void CReplayTurnManager::OnSyncError(u32 turn)
{
m_HasSyncError = true;
std::stringstream msg;
msg << "Out of sync on turn " << turn << "\n\n" << "The current game state is different from the original game state.";
LOGERROR("%s", msg.str());
if (g_GUI)
g_GUI->DisplayMessageBox(600, 350, L"Sync error", wstring_from_utf8(msg.str()));
}

View File

@ -41,8 +41,6 @@ private:
void DoTurn(u32 turn);
void OnSyncError(u32 turn);
// Contains the commands of every player on each turn
std::map<u32, std::vector<std::pair<player_id_t, std::string>>> m_ReplayCommands;