mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Prevent players to reveal the map from GUI script
`Engine.SetViewedPlayer` and `Engine.SetPlayerID` could be used to reveal the map from GUI scripts and the in game console. This is prevented by querying the simulation whether this player is allowed to call thous functions. These two vulnerabilities were introduced with their respective features:20e7d2224aintroduced SetPlayerID to allow controlling other players using the developer overlay.a2f7d4d82aintroduced SetViewedPlayer to allow observers to change the perspective.
This commit is contained in:
parent
40d3ea33d8
commit
023527e56e
3 changed files with 55 additions and 11 deletions
|
|
@ -74,6 +74,7 @@ CGame::CGame(bool replayLog):
|
|||
// should be created outside only if needed.
|
||||
m_GameView(CRenderer::IsInitialised() ? new CGameView(g_VideoMode.GetBackendDevice(), this) : nullptr),
|
||||
m_GameStarted(false),
|
||||
m_CheatsEnabled(false),
|
||||
m_Paused(false),
|
||||
m_SimRate(1.0f),
|
||||
m_PlayerID(-1),
|
||||
|
|
@ -221,6 +222,15 @@ void CGame::RegisterInit(const JS::HandleValue attribs, const std::string& saved
|
|||
std::string mapType;
|
||||
Script::GetProperty(rq, attribs, "mapType", mapType);
|
||||
|
||||
JS::RootedValue settings(rq.cx);
|
||||
Script::GetProperty(rq, attribs, "settings", &settings);
|
||||
|
||||
if (Script::HasProperty(rq, attribs, "settings") &&
|
||||
Script::HasProperty(rq, settings, "CheatsEnabled"))
|
||||
{
|
||||
Script::GetProperty(rq, settings, "CheatsEnabled", m_CheatsEnabled);
|
||||
}
|
||||
|
||||
float speed;
|
||||
if (Script::HasProperty(rq, attribs, "gameSpeed"))
|
||||
{
|
||||
|
|
@ -249,19 +259,14 @@ void CGame::RegisterInit(const JS::HandleValue attribs, const std::string& saved
|
|||
{
|
||||
// Load random map attributes
|
||||
std::wstring scriptFile;
|
||||
JS::RootedValue settings(rq.cx);
|
||||
|
||||
Script::GetProperty(rq, attribs, "script", scriptFile);
|
||||
Script::GetProperty(rq, attribs, "settings", &settings);
|
||||
|
||||
m_World->RegisterInitRMS(scriptFile, scriptInterface.GetContext(), settings, m_PlayerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring mapFile;
|
||||
JS::RootedValue settings(rq.cx);
|
||||
Script::GetProperty(rq, attribs, "map", mapFile);
|
||||
Script::GetProperty(rq, attribs, "settings", &settings);
|
||||
|
||||
m_World->RegisterInit(mapFile, scriptInterface.GetContext(), settings, m_PlayerID);
|
||||
}
|
||||
|
|
@ -379,6 +384,11 @@ void CGame::SetViewedPlayerID(player_id_t playerID)
|
|||
m_ViewedPlayerID = playerID;
|
||||
}
|
||||
|
||||
bool CGame::CheatsEnabled() const
|
||||
{
|
||||
return m_CheatsEnabled;
|
||||
}
|
||||
|
||||
void CGame::StartGame(JS::MutableHandleValue attribs, const std::string& savedState)
|
||||
{
|
||||
if (m_ReplayLogger)
|
||||
|
|
@ -475,3 +485,13 @@ bool CGame::IsGameFinished() const
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGame::PlayerFinished(player_id_t playerID) const
|
||||
{
|
||||
CmpPtr<ICmpPlayerManager> cmpPlayerManager(*m_Simulation2, SYSTEM_ENTITY);
|
||||
if (!cmpPlayerManager)
|
||||
return false;
|
||||
|
||||
CmpPtr<ICmpPlayer> cmpPlayer(*m_Simulation2, cmpPlayerManager->GetPlayerByID(playerID));
|
||||
return cmpPlayer && cmpPlayer->GetState() != "active";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2023 Wildfire Games.
|
||||
/* Copyright (C) 2024 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -114,6 +114,8 @@ public:
|
|||
int GetViewedPlayerID();
|
||||
void SetViewedPlayerID(player_id_t playerID);
|
||||
|
||||
bool CheatsEnabled() const;
|
||||
|
||||
/**
|
||||
* Check if the game is finished by testing if there's a winner.
|
||||
* It is used to end a non visual autostarted game.
|
||||
|
|
@ -122,6 +124,11 @@ public:
|
|||
*/
|
||||
bool IsGameFinished() const;
|
||||
|
||||
/**
|
||||
* Check if the given player has been defeated or won the game.
|
||||
*/
|
||||
bool PlayerFinished(player_id_t playerID) const;
|
||||
|
||||
/**
|
||||
* Retrieving player colors from scripts is slow, so this updates an
|
||||
* internal cache of all players' colors.
|
||||
|
|
@ -214,6 +221,8 @@ private:
|
|||
int LoadInitialState(const std::string& savedState);
|
||||
bool m_IsSavedGame; // true if loading a saved game; false for a new game
|
||||
|
||||
bool m_CheatsEnabled;
|
||||
|
||||
int LoadVisualReplayData();
|
||||
OsPath m_ReplayPath;
|
||||
bool m_IsVisualReplay;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2023 Wildfire Games.
|
||||
/* Copyright (C) 2024 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -67,20 +67,35 @@ int GetPlayerID()
|
|||
return g_Game->GetPlayerID();
|
||||
}
|
||||
|
||||
void SetPlayerID(int id)
|
||||
void SetPlayerID(const ScriptRequest& rq, int id)
|
||||
{
|
||||
if (!g_Game)
|
||||
return;
|
||||
|
||||
g_Game->SetPlayerID(id);
|
||||
int currentID = g_Game->GetPlayerID();
|
||||
if (currentID == id)
|
||||
return;
|
||||
|
||||
if (g_Game->CheatsEnabled())
|
||||
g_Game->SetPlayerID(id);
|
||||
else
|
||||
ScriptException::Raise(rq, "Changing player ID with cheats disabled is prohibited");
|
||||
}
|
||||
|
||||
void SetViewedPlayer(int id)
|
||||
void SetViewedPlayer(const ScriptRequest& rq, int id)
|
||||
{
|
||||
if (!g_Game)
|
||||
return;
|
||||
|
||||
g_Game->SetViewedPlayerID(id);
|
||||
int playerID = g_Game->GetPlayerID();
|
||||
if (playerID == id)
|
||||
return;
|
||||
|
||||
// Forbid active players to reveal the map by changing perspective, unless cheats are allowed.
|
||||
if (playerID == -1 || g_Game->CheatsEnabled() || g_Game->PlayerFinished(playerID))
|
||||
g_Game->SetViewedPlayerID(id);
|
||||
else
|
||||
ScriptException::Raise(rq, "Changing the perspective with cheats disabled is prohibited");
|
||||
}
|
||||
|
||||
float GetSimRate()
|
||||
|
|
|
|||
Loading…
Reference in a new issue