aboutsummaryrefslogtreecommitdiff
path: root/src/network/serverpackethandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/serverpackethandler.cpp')
-rw-r--r--src/network/serverpackethandler.cpp128
1 files changed, 73 insertions, 55 deletions
diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp
index fd5aed9d1..12dc24460 100644
--- a/src/network/serverpackethandler.cpp
+++ b/src/network/serverpackethandler.cpp
@@ -86,7 +86,7 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
// Do not allow multiple players in simple singleplayer mode.
// This isn't a perfect way to do it, but will suffice for now
- if (m_simple_singleplayer_mode && m_clients.getClientIDs().size() > 1) {
+ if (m_simple_singleplayer_mode && !m_clients.getClientIDs().empty()) {
infostream << "Server: Not allowing another client (" << addr_s <<
") to connect in simple singleplayer mode" << std::endl;
DenyAccess(peer_id, SERVER_ACCESSDENIED_SINGLEPLAYER);
@@ -174,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
@@ -352,16 +362,15 @@ void Server::handleCommand_RequestMedia(NetworkPacket* pkt)
session_t peer_id = pkt->getPeerId();
infostream << "Sending " << numfiles << " files to " <<
getPlayerName(peer_id) << std::endl;
- verbosestream << "TOSERVER_REQUEST_MEDIA: " << std::endl;
+ verbosestream << "TOSERVER_REQUEST_MEDIA: requested file(s)" << std::endl;
for (u16 i = 0; i < numfiles; i++) {
std::string name;
*pkt >> name;
- tosend.push_back(name);
- verbosestream << "TOSERVER_REQUEST_MEDIA: requested file "
- << name << std::endl;
+ tosend.emplace_back(name);
+ verbosestream << " " << name << std::endl;
}
sendRequestedMedia(peer_id, tosend);
@@ -473,7 +482,6 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
f32 yaw = (f32)f32yaw / 100.0f;
u32 keyPressed = 0;
- // default behavior (in case an old client doesn't send these)
f32 fov = 0;
u8 wanted_range = 0;
@@ -499,17 +507,7 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
playersao->setFov(fov);
playersao->setWantedRange(wanted_range);
- player->keyPressed = keyPressed;
- player->control.up = (keyPressed & (0x1 << 0));
- player->control.down = (keyPressed & (0x1 << 1));
- player->control.left = (keyPressed & (0x1 << 2));
- player->control.right = (keyPressed & (0x1 << 3));
- player->control.jump = (keyPressed & (0x1 << 4));
- player->control.aux1 = (keyPressed & (0x1 << 5));
- player->control.sneak = (keyPressed & (0x1 << 6));
- player->control.dig = (keyPressed & (0x1 << 7));
- player->control.place = (keyPressed & (0x1 << 8));
- player->control.zoom = (keyPressed & (0x1 << 9));
+ player->control.unpackKeysPressed(keyPressed);
if (playersao->checkMovementCheat()) {
// Call callbacks
@@ -821,8 +819,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt)
<< std::endl;
PlayerHPChangeReason reason(PlayerHPChangeReason::FALL);
- playersao->setHP((s32)playersao->getHP() - (s32)damage, reason);
- SendPlayerHPOrDie(playersao, reason);
+ playersao->setHP((s32)playersao->getHP() - (s32)damage, reason, true);
}
}
@@ -916,6 +913,13 @@ bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std:
return true;
}
+// Tiny helper to retrieve the selected item into an Optional
+static inline void getWieldedItem(const PlayerSAO *playersao, Optional<ItemStack> &ret)
+{
+ ret = ItemStack();
+ playersao->getWieldedItem(&(*ret));
+}
+
void Server::handleCommand_Interact(NetworkPacket *pkt)
{
/*
@@ -1107,11 +1111,8 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
float time_from_last_punch =
playersao->resetTimeFromLastPunch();
- u16 src_original_hp = pointed_object->getHP();
- u16 dst_origin_hp = playersao->getHP();
-
- u16 wear = pointed_object->punch(dir, &toolcap, playersao,
- time_from_last_punch);
+ u32 wear = pointed_object->punch(dir, &toolcap, playersao,
+ time_from_last_punch, tool_item.wear);
// Callback may have changed item, so get it again
playersao->getWieldedItem(&selected_item);
@@ -1119,18 +1120,6 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
if (changed)
playersao->setWieldedItem(selected_item);
- // If the object is a player and its HP changed
- if (src_original_hp != pointed_object->getHP() &&
- pointed_object->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
- SendPlayerHPOrDie((PlayerSAO *)pointed_object,
- PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, playersao));
- }
-
- // If the puncher is a player and its HP changed
- if (dst_origin_hp != playersao->getHP())
- SendPlayerHPOrDie(playersao,
- PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, pointed_object));
-
return;
} // action == INTERACT_START_DIGGING
@@ -1176,7 +1165,8 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
// Get diggability and expected digging time
DigParams params = getDigParams(m_nodedef->get(n).groups,
- &selected_item.getToolCapabilities(m_itemdef));
+ &selected_item.getToolCapabilities(m_itemdef),
+ selected_item.wear);
// If can't dig, try hand
if (!params.diggable) {
params = getDigParams(m_nodedef->get(n).groups,
@@ -1238,14 +1228,17 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
// Place block or right-click object
case INTERACT_PLACE: {
- ItemStack selected_item;
- playersao->getWieldedItem(&selected_item, nullptr);
+ Optional<ItemStack> selected_item;
+ getWieldedItem(playersao, selected_item);
// Reset build time counter
if (pointed.type == POINTEDTHING_NODE &&
- selected_item.getDefinition(m_itemdef).type == ITEM_NODE)
+ selected_item->getDefinition(m_itemdef).type == ITEM_NODE)
getClient(peer_id)->m_time_from_building = 0.0;
+ const bool had_prediction = !selected_item->getDefinition(m_itemdef).
+ node_placement_prediction.empty();
+
if (pointed.type == POINTEDTHING_OBJECT) {
// Right click object
@@ -1258,11 +1251,9 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
<< pointed_object->getDescription() << std::endl;
// Do stuff
- if (m_script->item_OnSecondaryUse(
- selected_item, playersao, pointed)) {
- if (playersao->setWieldedItem(selected_item)) {
+ if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) {
+ if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
SendInventory(playersao, true);
- }
}
pointed_object->rightClick(playersao);
@@ -1270,7 +1261,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
// Placement was handled in lua
// Apply returned ItemStack
- if (playersao->setWieldedItem(selected_item))
+ if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
SendInventory(playersao, true);
}
@@ -1282,8 +1273,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
RemoteClient *client = getClient(peer_id);
v3s16 blockpos = getNodeBlockPos(pointed.node_abovesurface);
v3s16 blockpos2 = getNodeBlockPos(pointed.node_undersurface);
- if (!selected_item.getDefinition(m_itemdef
- ).node_placement_prediction.empty()) {
+ if (had_prediction) {
client->SetBlockNotSent(blockpos);
if (blockpos2 != blockpos)
client->SetBlockNotSent(blockpos2);
@@ -1297,15 +1287,15 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
} // action == INTERACT_PLACE
case INTERACT_USE: {
- ItemStack selected_item;
- playersao->getWieldedItem(&selected_item, nullptr);
+ Optional<ItemStack> selected_item;
+ getWieldedItem(playersao, selected_item);
- actionstream << player->getName() << " uses " << selected_item.name
+ actionstream << player->getName() << " uses " << selected_item->name
<< ", pointing at " << pointed.dump() << std::endl;
if (m_script->item_OnUse(selected_item, playersao, pointed)) {
// Apply returned ItemStack
- if (playersao->setWieldedItem(selected_item))
+ if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
SendInventory(playersao, true);
}
@@ -1314,16 +1304,17 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
// Rightclick air
case INTERACT_ACTIVATE: {
- ItemStack selected_item;
- playersao->getWieldedItem(&selected_item, nullptr);
+ Optional<ItemStack> selected_item;
+ getWieldedItem(playersao, selected_item);
actionstream << player->getName() << " activates "
- << selected_item.name << std::endl;
+ << selected_item->name << std::endl;
pointed.type = POINTEDTHING_NOTHING; // can only ever be NOTHING
if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) {
- if (playersao->setWieldedItem(selected_item))
+ // Apply returned ItemStack
+ if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
SendInventory(playersao, true);
}
@@ -1811,3 +1802,30 @@ void Server::handleCommand_ModChannelMsg(NetworkPacket *pkt)
broadcastModChannelMessage(channel_name, channel_msg, peer_id);
}
+
+void Server::handleCommand_HaveMedia(NetworkPacket *pkt)
+{
+ std::vector<u32> tokens;
+ u8 numtokens;
+
+ *pkt >> numtokens;
+ for (u16 i = 0; i < numtokens; i++) {
+ u32 n;
+ *pkt >> n;
+ tokens.emplace_back(n);
+ }
+
+ const session_t peer_id = pkt->getPeerId();
+ auto player = m_env->getPlayer(peer_id);
+
+ for (const u32 token : tokens) {
+ auto it = m_pending_dyn_media.find(token);
+ if (it == m_pending_dyn_media.end())
+ continue;
+ if (it->second.waiting_players.count(peer_id)) {
+ it->second.waiting_players.erase(peer_id);
+ if (player)
+ getScriptIface()->on_dynamic_media_added(token, player->getName());
+ }
+ }
+}