aboutsummaryrefslogtreecommitdiff
path: root/src/network/serverpackethandler.cpp
diff options
context:
space:
mode:
authorMinetest-j45 <55553015+Minetest-j45@users.noreply.github.com>2021-08-30 15:22:40 +0100
committerGitHub <noreply@github.com>2021-08-30 15:22:40 +0100
commit7824a4956bf489b4e2cc35e0c97272eee06be6ba (patch)
tree70243765dc1743a83596f9c6eec122fb417ef92c /src/network/serverpackethandler.cpp
parent607add326feb44e078b843464ce4a8de09f28743 (diff)
parent35445d24f425c6291a0580b468919ca83de716fd (diff)
downloaddragonfireclient-7824a4956bf489b4e2cc35e0c97272eee06be6ba.tar.xz
Merge pull request #1 from EliasFleckenstein03/master
update
Diffstat (limited to 'src/network/serverpackethandler.cpp')
-rw-r--r--src/network/serverpackethandler.cpp109
1 files changed, 60 insertions, 49 deletions
diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp
index c636d01e1..708ddbf20 100644
--- a/src/network/serverpackethandler.cpp
+++ b/src/network/serverpackethandler.cpp
@@ -56,12 +56,12 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
session_t peer_id = pkt->getPeerId();
RemoteClient *client = getClient(peer_id, CS_Created);
+ Address addr;
std::string addr_s;
try {
- Address address = getPeerAddress(peer_id);
- addr_s = address.serializeString();
- }
- catch (con::PeerNotFoundException &e) {
+ addr = m_con->GetPeerAddress(peer_id);
+ addr_s = addr.serializeString();
+ } catch (con::PeerNotFoundException &e) {
/*
* no peer for this packet found
* most common reason is peer timeout, e.g. peer didn't
@@ -73,13 +73,14 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
return;
}
- // If net_proto_version is set, this client has already been handled
if (client->getState() > CS_Created) {
verbosestream << "Server: Ignoring multiple TOSERVER_INITs from " <<
addr_s << " (peer_id=" << peer_id << ")" << std::endl;
return;
}
+ client->setCachedAddress(addr);
+
verbosestream << "Server: Got TOSERVER_INIT from " << addr_s <<
" (peer_id=" << peer_id << ")" << std::endl;
@@ -173,6 +174,16 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
return;
}
+ RemotePlayer *player = m_env->getPlayer(playername);
+
+ // If player is already connected, cancel
+ if (player && player->getPeerId() != PEER_ID_INEXISTENT) {
+ actionstream << "Server: Player with name \"" << playername <<
+ "\" tried to connect, but player with same name is already connected" << std::endl;
+ DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED);
+ return;
+ }
+
m_clients.setPlayerName(peer_id, playername);
//TODO (later) case insensitivity
@@ -437,18 +448,20 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt)
u8 count;
*pkt >> count;
- RemoteClient *client = getClient(pkt->getPeerId());
-
if ((s16)pkt->getSize() < 1 + (int)count * 6) {
throw con::InvalidIncomingDataException
("GOTBLOCKS length is too short");
}
+ m_clients.lock();
+ RemoteClient *client = m_clients.lockedGetClientNoEx(pkt->getPeerId());
+
for (u16 i = 0; i < count; i++) {
v3s16 p;
*pkt >> p;
client->GotBlock(p);
}
+ m_clients.unlock();
}
void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
@@ -485,8 +498,12 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
pitch = modulo360f(pitch);
yaw = wrapDegrees_0_360(yaw);
- playersao->setBasePosition(position);
- player->setSpeed(speed);
+ if (!playersao->isAttached()) {
+ // Only update player positions when moving freely
+ // to not interfere with attachment handling
+ playersao->setBasePosition(position);
+ player->setSpeed(speed);
+ }
playersao->setLookPitch(pitch);
playersao->setPlayerYaw(yaw);
playersao->setFov(fov);
@@ -619,21 +636,36 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
const bool player_has_interact = checkPriv(player->getName(), "interact");
- auto check_inv_access = [player, player_has_interact] (
+ auto check_inv_access = [player, player_has_interact, this] (
const InventoryLocation &loc) -> bool {
- if (loc.type == InventoryLocation::CURRENT_PLAYER)
- return false; // Only used internally on the client, never sent
- if (loc.type == InventoryLocation::PLAYER) {
- // Allow access to own inventory in all cases
- return loc.name == player->getName();
- }
- if (!player_has_interact) {
+ // Players without interact may modify their own inventory
+ if (!player_has_interact && loc.type != InventoryLocation::PLAYER) {
infostream << "Cannot modify foreign inventory: "
<< "No interact privilege" << std::endl;
return false;
}
- return true;
+
+ switch (loc.type) {
+ case InventoryLocation::CURRENT_PLAYER:
+ // Only used internally on the client, never sent
+ return false;
+ case InventoryLocation::PLAYER:
+ // Allow access to own inventory in all cases
+ return loc.name == player->getName();
+ case InventoryLocation::NODEMETA:
+ {
+ // Check for out-of-range interaction
+ v3f node_pos = intToFloat(loc.p, BS);
+ v3f player_pos = player->getPlayerSAO()->getEyePosition();
+ f32 d = player_pos.getDistanceFrom(node_pos);
+ return checkInteractDistance(player, d, "inventory");
+ }
+ case InventoryLocation::DETACHED:
+ return getInventoryMgr()->checkDetachedInventoryAccess(loc, player->getName());
+ default:
+ return false;
+ }
};
/*
@@ -653,18 +685,6 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
!check_inv_access(ma->to_inv))
return;
- InventoryLocation *remote = ma->from_inv.type == InventoryLocation::PLAYER ?
- &ma->to_inv : &ma->from_inv;
-
- // Check for out-of-range interaction
- if (remote->type == InventoryLocation::NODEMETA) {
- v3f node_pos = intToFloat(remote->p, BS);
- v3f player_pos = player->getPlayerSAO()->getEyePosition();
- f32 d = player_pos.getDistanceFrom(node_pos);
- if (!checkInteractDistance(player, d, "inventory"))
- return;
- }
-
/*
Disable moving items out of craftpreview
*/
@@ -749,21 +769,8 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
void Server::handleCommand_ChatMessage(NetworkPacket* pkt)
{
- /*
- u16 command
- u16 length
- wstring message
- */
- u16 len;
- *pkt >> len;
-
std::wstring message;
- for (u16 i = 0; i < len; i++) {
- u16 tmp_wchar;
- *pkt >> tmp_wchar;
-
- message += (wchar_t)tmp_wchar;
- }
+ *pkt >> message;
session_t peer_id = pkt->getPeerId();
RemotePlayer *player = m_env->getPlayer(peer_id);
@@ -775,15 +782,13 @@ void Server::handleCommand_ChatMessage(NetworkPacket* pkt)
return;
}
- // Get player name of this client
std::string name = player->getName();
- std::wstring wname = narrow_to_wide(name);
- std::wstring answer_to_sender = handleChat(name, wname, message, true, player);
+ std::wstring answer_to_sender = handleChat(name, message, true, player);
if (!answer_to_sender.empty()) {
// Send the answer to sender
- SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_NORMAL,
- answer_to_sender, wname));
+ SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
+ answer_to_sender));
}
}
@@ -1046,6 +1051,12 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
if (pointed.type == POINTEDTHING_NODE) {
target_pos = intToFloat(pointed.node_undersurface, BS);
} else if (pointed.type == POINTEDTHING_OBJECT) {
+ if (playersao->getId() == pointed_object->getId()) {
+ actionstream << "Server: " << player->getName()
+ << " attempted to interact with themselves" << std::endl;
+ m_script->on_cheat(playersao, "interacted_with_self");
+ return;
+ }
target_pos = pointed_object->getBasePosition();
}
float d = playersao->getEyePosition().getDistanceFrom(target_pos);