Merge 78a79b8ae9
into a4d2633ac6
This commit is contained in:
commit
cb421cfafb
@ -776,17 +776,20 @@ enum ToServerCommand : u16
|
||||
|
||||
TOSERVER_INTERACT = 0x39,
|
||||
/*
|
||||
[0] u16 command
|
||||
[2] u8 action
|
||||
[3] u16 item
|
||||
[5] u32 length of the next item
|
||||
[9] serialized PointedThing
|
||||
actions:
|
||||
0: start digging (from undersurface) or use
|
||||
1: stop digging (all parameters ignored)
|
||||
2: digging completed
|
||||
3: place block or item (to abovesurface)
|
||||
4: use item
|
||||
u16 command
|
||||
u8 action (InteractAction)
|
||||
u16 item
|
||||
u32 length of the next item
|
||||
u8[length] serialized PointedThing
|
||||
v3s32 player position multiplied by 100 and converted to integers
|
||||
v3s32 player speed multiplied by 100 and converted to integers
|
||||
s32 player pitch multiplied by 100 and converted to an integer
|
||||
s32 player yaw multiplied by 100 and converted to an integer
|
||||
u32 keyPressed
|
||||
u8 fov
|
||||
u8 wanted drawing range
|
||||
optional:
|
||||
u8 flags; it is 0x01 if the camera is inverted
|
||||
*/
|
||||
|
||||
TOSERVER_REMOVED_SOUNDS = 0x3a,
|
||||
|
@ -878,15 +878,6 @@ static inline void getWieldedItem(const PlayerSAO *playersao, std::optional<Item
|
||||
|
||||
void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||
{
|
||||
/*
|
||||
[0] u16 command
|
||||
[2] u8 action
|
||||
[3] u16 item
|
||||
[5] u32 length of the next item (plen)
|
||||
[9] serialized PointedThing
|
||||
[9 + plen] player position information
|
||||
*/
|
||||
|
||||
InteractAction action;
|
||||
u16 item_i;
|
||||
|
||||
@ -923,13 +914,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||
if (playersao->isDead()) {
|
||||
actionstream << "Server: " << player->getName()
|
||||
<< " tried to interact while dead; ignoring." << std::endl;
|
||||
if (pointed.type == POINTEDTHING_NODE) {
|
||||
// Re-send block to revert change on client-side
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
v3s16 blockpos = getNodeBlockPos(pointed.node_undersurface);
|
||||
client->SetBlockNotSent(blockpos);
|
||||
}
|
||||
// Call callbacks
|
||||
getClient(peer_id)->respondToInteraction(action, pointed, false);
|
||||
m_script->on_cheat(playersao, "interacted_while_dead");
|
||||
return;
|
||||
}
|
||||
@ -969,22 +954,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||
if (!checkPriv(player->getName(), "interact")) {
|
||||
actionstream << player->getName() << " attempted to interact with " <<
|
||||
pointed.dump() << " without 'interact' privilege" << std::endl;
|
||||
|
||||
if (pointed.type != POINTEDTHING_NODE)
|
||||
return;
|
||||
|
||||
// Re-send block to revert change on client-side
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
// Digging completed -> under
|
||||
if (action == INTERACT_DIGGING_COMPLETED) {
|
||||
v3s16 blockpos = getNodeBlockPos(pointed.node_undersurface);
|
||||
client->SetBlockNotSent(blockpos);
|
||||
}
|
||||
// Placement -> above
|
||||
else if (action == INTERACT_PLACE) {
|
||||
v3s16 blockpos = getNodeBlockPos(pointed.node_abovesurface);
|
||||
client->SetBlockNotSent(blockpos);
|
||||
}
|
||||
getClient(peer_id)->respondToInteraction(action, pointed, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1012,12 +982,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||
float d = playersao->getEyePosition().getDistanceFrom(target_pos);
|
||||
|
||||
if (!checkInteractDistance(player, d, pointed.dump())) {
|
||||
if (pointed.type == POINTEDTHING_NODE) {
|
||||
// Re-send block to revert change on client-side
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
v3s16 blockpos = getNodeBlockPos(pointed.node_undersurface);
|
||||
client->SetBlockNotSent(blockpos);
|
||||
}
|
||||
getClient(peer_id)->respondToInteraction(action, pointed, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1170,14 +1135,12 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||
if (is_valid_dig && n.getContent() != CONTENT_IGNORE)
|
||||
m_script->node_on_dig(p_under, n, playersao);
|
||||
|
||||
v3s16 blockpos = getNodeBlockPos(p_under);
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
// Send unusual result (that is, node not being removed)
|
||||
if (m_env->getMap().getNode(p_under).getContent() != CONTENT_AIR)
|
||||
// Re-send block to revert change on client-side
|
||||
client->SetBlockNotSent(blockpos);
|
||||
else
|
||||
client->ResendBlockIfOnWire(blockpos);
|
||||
// For whatever reason we assume that the client always predicts that a
|
||||
// dug node is air irrespective of the node's node_dig_prediction
|
||||
bool prediction_success =
|
||||
m_env->getMap().getNode(p_under).getContent() == CONTENT_AIR;
|
||||
getClient(peer_id)->respondToInteraction(action, pointed,
|
||||
prediction_success);
|
||||
|
||||
return;
|
||||
} // action == INTERACT_DIGGING_COMPLETED
|
||||
@ -1221,24 +1184,11 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||
SendInventory(player, true);
|
||||
}
|
||||
|
||||
if (pointed.type != POINTEDTHING_NODE)
|
||||
return;
|
||||
|
||||
// If item has node placement prediction, always send the
|
||||
// blocks to make sure the client knows what exactly happened
|
||||
RemoteClient *client = getClient(peer_id);
|
||||
v3s16 blockpos = getNodeBlockPos(pointed.node_abovesurface);
|
||||
v3s16 blockpos2 = getNodeBlockPos(pointed.node_undersurface);
|
||||
if (had_prediction) {
|
||||
client->SetBlockNotSent(blockpos);
|
||||
if (blockpos2 != blockpos)
|
||||
client->SetBlockNotSent(blockpos2);
|
||||
} else {
|
||||
client->ResendBlockIfOnWire(blockpos);
|
||||
if (blockpos2 != blockpos)
|
||||
client->ResendBlockIfOnWire(blockpos2);
|
||||
}
|
||||
|
||||
// Since we do not known if the client has predicted the node at
|
||||
// pointed.above or pointed.under,
|
||||
// we assume that a prediction is always wrong.
|
||||
getClient(peer_id)->respondToInteraction(action, pointed,
|
||||
!had_prediction);
|
||||
return;
|
||||
} // action == INTERACT_PLACE
|
||||
|
||||
|
@ -65,14 +65,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;
|
||||
@ -457,6 +449,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;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "porting.h"
|
||||
#include "threading/mutex_auto_lock.h"
|
||||
#include "clientdynamicinfo.h"
|
||||
#include "util/pointedthing.h"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
@ -255,12 +256,17 @@ public:
|
||||
void SetBlocksNotSent(const std::vector<v3s16> &blocks);
|
||||
|
||||
/**
|
||||
* tell client about this block being modified right now.
|
||||
* this information is required to requeue the block in case it's "on wire"
|
||||
* while modification is processed by server
|
||||
* @param p position of modified block
|
||||
* Trigger block sending to undo client-side predicted node changes
|
||||
*
|
||||
* \param action The interact action to determine which predictions the
|
||||
* client could have made
|
||||
* \param pointed The positions where the client has interacted
|
||||
* \param prediction_success If true, assume that the client has made a
|
||||
* correct prediction and send the mapblock only if an outdated mapblock
|
||||
* is currently "on wire", which can erroneously override the prediction
|
||||
*/
|
||||
void ResendBlockIfOnWire(v3s16 p);
|
||||
void respondToInteraction(InteractAction action,
|
||||
const PointedThing &pointed, bool prediction_success);
|
||||
|
||||
u32 getSendingCount() const { return m_blocks_sending.size(); }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user