Prevent players from hiding Fog of War layers
Some checks are pending
Windows Release / windows-x86_64 (push) Waiting to run
Some checks are pending
Windows Release / windows-x86_64 (push) Waiting to run
Clients could toggle fog visibility (and fade alpha); DisplayData synced that to everyone and defeated FoW. Block client set_visible/set_alpha, clamp host-side DisplayData updates, and ignore eye toggles for fog. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
fea392b65d
commit
3140f9bb55
4 changed files with 31 additions and 3 deletions
|
|
@ -20,6 +20,7 @@
|
|||
#include "DrawingProgramLayerFolder.hpp"
|
||||
#include <cereal/types/string.hpp>
|
||||
#include "DrawingProgramLayer.hpp"
|
||||
#include "FogStripper.hpp"
|
||||
#include "../../World.hpp"
|
||||
#include "../../MainProgram.hpp"
|
||||
#include "SerializedBlendMode.hpp"
|
||||
|
|
@ -258,6 +259,9 @@ const std::string& DrawingProgramLayerListItem::get_name() const {
|
|||
}
|
||||
|
||||
void DrawingProgramLayerListItem::set_alpha(DrawingProgramLayerManager& layerMan, float newAlpha) const {
|
||||
// Players must not fade fog out — same authority as visibility.
|
||||
if(is_fog_layer() && !FogStripper::world_is_host(layerMan.drawP.world))
|
||||
return;
|
||||
if(displayData && displayData->alpha != newAlpha) {
|
||||
displayData->alpha = newAlpha;
|
||||
layerMan.drawP.drawCache.clear_own_cached_surfaces();
|
||||
|
|
@ -270,6 +274,9 @@ float DrawingProgramLayerListItem::get_alpha() const {
|
|||
}
|
||||
|
||||
void DrawingProgramLayerListItem::set_visible(DrawingProgramLayerManager& layerMan, bool newVisible) const {
|
||||
// Fog of War is host-controlled; clients hiding it would sync and strip FoW for everyone.
|
||||
if(is_fog_layer() && !FogStripper::world_is_host(layerMan.drawP.world))
|
||||
return;
|
||||
if(displayData && displayData->visible != newVisible) {
|
||||
displayData->visible = newVisible;
|
||||
layerMan.drawP.drawCache.clear_own_cached_surfaces();
|
||||
|
|
@ -393,6 +400,24 @@ void DrawingProgramLayerListItem::register_class(World& w) {
|
|||
}
|
||||
});
|
||||
w.delayedUpdateObjectManager.register_class<DisplayData>(w.netObjMan, NetworkingObjects::DelayUpdateSerializedClassManager::CustomConstructors<DisplayData>{
|
||||
.readUpdate = [](DisplayData& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) {
|
||||
DisplayData incoming;
|
||||
a(incoming);
|
||||
// Client→host: never allow stripping fog, unlocking, hiding, or fading fog.
|
||||
if(c) {
|
||||
if(o.fogLayer || incoming.fogLayer) {
|
||||
incoming.fogLayer = true;
|
||||
incoming.playerLocked = true;
|
||||
incoming.visible = true;
|
||||
incoming.alpha = o.alpha;
|
||||
}
|
||||
else {
|
||||
incoming.fogLayer = false;
|
||||
incoming.playerLocked = o.playerLocked;
|
||||
}
|
||||
}
|
||||
o = incoming;
|
||||
},
|
||||
.postUpdateFunc = [&](DisplayData& o) {
|
||||
(void)o;
|
||||
w.drawProg.drawCache.clear_own_cached_surfaces();
|
||||
|
|
|
|||
|
|
@ -144,11 +144,14 @@ void DrawingProgramLayerManagerGUI::setup_list_gui() {
|
|||
});
|
||||
}
|
||||
gui.set_z_index_keep_clipping_region(gui.get_z_index() + 1, [&] {
|
||||
// Fog stays visible for players — eye is informational only on clients.
|
||||
const bool fogVisibilityLocked = layer->is_fog_layer() && !FogStripper::world_is_host(world);
|
||||
svg_icon_button(gui, "visible button", layer->get_visible() ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.size = TreeListing::ENTRY_HEIGHT,
|
||||
.onClick = [&, layer] {
|
||||
layer->set_visible(layerMan, !layer->get_visible());
|
||||
.onClick = [&, layer, fogVisibilityLocked] {
|
||||
if(!fogVisibilityLocked)
|
||||
layer->set_visible(layerMan, !layer->get_visible());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue