1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-30 19:22:14 +00:00

Refactor server-side node placement or dig prediction handling

The code for handling `TOSERVER_INTERACT` packets has some style-related
problems:
* There are five places with mapblock-sending code to undo predictions in
  the large `handleCommand_Interact` method in `serverpackethandler.cpp`,
  so these can be abstracted away into a function to shorten the code.
* In `networkprotocol.h`, below `TOSERVER_INTERACT`,
  there is an outdated copy of the `InteractAction` enum
  documentation and the player position information is not mentioned.
* In `serverpackethandler.cpp`, there is a (newer) copy of the
  `TOSERVER_INTERACT` documentation from `networkprotocol.h`.

Furthermore, the way the server undoes or confirms client-side node placement
or dig predictions looks inconsistent, thus erroneous:
* If a player tries to place a node in a distance too far away or if he/she
  is dead,
  only the mapblock containing `pointed.node_undersurface` is triggered to be
  sent although the player may have placed the node at
  `pointed.node_abovesurface` and this position may be in a different mapblock.
* Similarly, if a player without interact privilege tries to place a node,
  only the mapblock containing `pointed.node_abovesurface` is triggered to be
  sent although the player may have placed the node at
  `pointed.node_undersurface` and this position may be in a different mapblock.

This change addresses the problems listed above:
* Fix the documentation comments related to the TOSERVER_INTERACT package
  content
* Move mapblock sending code related to predictions to ClientInterface
* If the player tries to place but has no interact privilege, is dead,
  or exceeds the permitted distance,
  send both the mapblock corresponding to `pointed.node_undersurface` and
  `pointed.node_abovesurface` if these mapblocks differ
This commit is contained in:
HybridDog 2024-01-24 22:03:11 +01:00
parent dc7a7a0ed9
commit 6327101607
4 changed files with 64 additions and 88 deletions

View file

@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server/luaentity_sao.h"
#include "server/player_sao.h"
#include "log.h"
#include "util/pointedthing.h"
#include "util/srp.h"
#include "util/string.h"
#include "face_position_cache.h"
@ -77,14 +78,6 @@ RemoteClient::RemoteClient() :
{
}
void RemoteClient::ResendBlockIfOnWire(v3s16 p)
{
// if this block is on wire, mark it for sending again as soon as possible
if (m_blocks_sending.find(p) != m_blocks_sending.end()) {
SetBlockNotSent(p);
}
}
static LuaEntitySAO *getAttachedObject(PlayerSAO *sao, ServerEnvironment *env)
{
ServerActiveObject *ao = sao;
@ -469,6 +462,30 @@ void RemoteClient::SetBlocksNotSent(const std::vector<v3s16> &blocks)
}
}
void RemoteClient::respondToInteraction(InteractAction action,
const PointedThing &pointed, bool prediction_success)
{
if ((action != INTERACT_PLACE && action != INTERACT_DIGGING_COMPLETED)
|| pointed.type != POINTEDTHING_NODE)
// The client has not predicted not node changes
return;
// The client may have an outdated mapblock if the placement or dig
// prediction was wrong or if an old mapblock is still being sent to it.
v3s16 blockpos = getNodeBlockPos(pointed.node_undersurface);
if (!prediction_success
|| m_blocks_sending.find(blockpos) != m_blocks_sending.end()) {
SetBlockNotSent(blockpos);
}
if (action != INTERACT_PLACE)
return;
v3s16 blockpos2 = getNodeBlockPos(pointed.node_abovesurface);
if (blockpos2 != blockpos && (!prediction_success
|| m_blocks_sending.find(blockpos2) != m_blocks_sending.end())) {
SetBlockNotSent(blockpos2);
}
}
void RemoteClient::notifyEvent(ClientStateEvent event)
{
std::ostringstream myerror;