forked from Mirrorlandia_minetest/minetest
FOV: Raise lower limit to avoid zoom-loading of distant world (#7234)
In the client, raise lower limit from 30 to 45 degrees, to avoid server seeing this as a zoom and loading world beyond the server-set limit. Add minimum in settingtypes.txt and enforce lower limit when set using minetest.conf. In the server, distrust the client-sent FOV if below the heuristic zoom threshold and use the player object property 'zoom_fov' to check it, to protect against hacked clients.
This commit is contained in:
parent
326eeca306
commit
28813702d6
@ -574,7 +574,7 @@ fullscreen_bpp (Full screen BPP) int 24
|
|||||||
vsync (V-Sync) bool false
|
vsync (V-Sync) bool false
|
||||||
|
|
||||||
# Field of view in degrees.
|
# Field of view in degrees.
|
||||||
fov (Field of view) int 72 30 160
|
fov (Field of view) int 72 45 160
|
||||||
|
|
||||||
# Adjust the gamma encoding for the light tables. Higher numbers are brighter.
|
# Adjust the gamma encoding for the light tables. Higher numbers are brighter.
|
||||||
# This setting is for the client only and is ignored by the server.
|
# This setting is for the client only and is ignored by the server.
|
||||||
|
@ -71,7 +71,9 @@ Camera::Camera(MapDrawControl &draw_control, Client *client):
|
|||||||
*/
|
*/
|
||||||
m_cache_fall_bobbing_amount = g_settings->getFloat("fall_bobbing_amount");
|
m_cache_fall_bobbing_amount = g_settings->getFloat("fall_bobbing_amount");
|
||||||
m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount");
|
m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount");
|
||||||
m_cache_fov = g_settings->getFloat("fov");
|
// 45 degrees is the lowest FOV that doesn't cause the server to treat this
|
||||||
|
// as a zoom FOV and load world beyond the set server limits.
|
||||||
|
m_cache_fov = std::fmax(g_settings->getFloat("fov"), 45.0f);
|
||||||
m_arm_inertia = g_settings->getBool("arm_inertia");
|
m_arm_inertia = g_settings->getBool("arm_inertia");
|
||||||
m_nametags.clear();
|
m_nametags.clear();
|
||||||
}
|
}
|
||||||
|
@ -192,17 +192,35 @@ void RemoteClient::GetNextBlocks (
|
|||||||
*/
|
*/
|
||||||
s32 new_nearest_unsent_d = -1;
|
s32 new_nearest_unsent_d = -1;
|
||||||
|
|
||||||
// get view range and camera fov from the client
|
// Get view range and camera fov (radians) from the client
|
||||||
s16 wanted_range = sao->getWantedRange() + 1;
|
s16 wanted_range = sao->getWantedRange() + 1;
|
||||||
float camera_fov = sao->getFov();
|
float camera_fov = sao->getFov();
|
||||||
|
|
||||||
const s16 full_d_max = std::min(adjustDist(m_max_send_distance, camera_fov), wanted_range);
|
// If below the heuristic zoom threshold (see adjustDist() in numeric.cpp)
|
||||||
const s16 d_opt = std::min(adjustDist(m_block_optimize_distance, camera_fov), wanted_range);
|
// distrust client-sent FOV and get server-set player object property
|
||||||
|
// zoom FOV (degrees) as a check to avoid hacked clients using FOV to load
|
||||||
|
// distant world.
|
||||||
|
// 0.888 radians is slightly larger than the zoom threshold of 1.775 / 2
|
||||||
|
// radians.
|
||||||
|
if (camera_fov < 0.888f) {
|
||||||
|
float prop_zoom_fov = sao->getZoomFOV();
|
||||||
|
// If zoom is disabled by value 0
|
||||||
|
if (prop_zoom_fov < 0.001f)
|
||||||
|
camera_fov = 0.888f;
|
||||||
|
else
|
||||||
|
// Degrees -> radians
|
||||||
|
camera_fov = prop_zoom_fov * core::DEGTORAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
const s16 full_d_max = std::min(adjustDist(m_max_send_distance, camera_fov),
|
||||||
|
wanted_range);
|
||||||
|
const s16 d_opt = std::min(adjustDist(m_block_optimize_distance, camera_fov),
|
||||||
|
wanted_range);
|
||||||
const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE;
|
const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE;
|
||||||
//infostream << "Fov from client " << camera_fov << " full_d_max " << full_d_max << std::endl;
|
|
||||||
|
|
||||||
s16 d_max = full_d_max;
|
s16 d_max = full_d_max;
|
||||||
s16 d_max_gen = std::min(adjustDist(m_max_gen_distance, camera_fov), wanted_range);
|
s16 d_max_gen = std::min(adjustDist(m_max_gen_distance, camera_fov),
|
||||||
|
wanted_range);
|
||||||
|
|
||||||
// Don't loop very much at a time, adjust with distance,
|
// Don't loop very much at a time, adjust with distance,
|
||||||
// do more work per RTT with greater distances.
|
// do more work per RTT with greater distances.
|
||||||
|
@ -1473,3 +1473,8 @@ bool PlayerSAO::getSelectionBox(aabb3f *toset) const
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float PlayerSAO::getZoomFOV() const
|
||||||
|
{
|
||||||
|
return m_prop.zoom_fov;
|
||||||
|
}
|
||||||
|
@ -330,6 +330,7 @@ public:
|
|||||||
|
|
||||||
v3f getEyePosition() const { return m_base_position + getEyeOffset(); }
|
v3f getEyePosition() const { return m_base_position + getEyeOffset(); }
|
||||||
v3f getEyeOffset() const;
|
v3f getEyeOffset() const;
|
||||||
|
float getZoomFOV() const;
|
||||||
|
|
||||||
inline Metadata &getMeta() { return m_meta; }
|
inline Metadata &getMeta() { return m_meta; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user