Skip to content

Commit

Permalink
feat: implement ProxiedCommandSender
Browse files Browse the repository at this point in the history
  • Loading branch information
wu-vincent committed Feb 10, 2025
1 parent 3b5a0c4 commit df567c9
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 31 deletions.
6 changes: 3 additions & 3 deletions include/endstone/command/proxied_command_sender.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@
namespace endstone {

/**
* @brief Interface for proxied command sender
* @brief Represents a proxied command sender
*/
class ProxiedCommandSender : public CommandSender {
public:
/**
* @brief Returns the CommandSender which triggered this proxied command.
*
* @return a shared pointer to the caller which triggered the command
* @return the caller which triggered the command
*/
[[nodiscard]] virtual CommandSender &getCaller() const = 0;

/**
* @brief Returns the CommandSender which is being used to call the command.
*
* @return a shared pointer to the caller which the command is being run as
* @return the caller which the command is being run as
*/
[[nodiscard]] virtual CommandSender &getCallee() const = 0;
};
Expand Down
19 changes: 17 additions & 2 deletions src/bedrock/server/commands/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,24 @@
#include <cstdint>

#include "bedrock/bedrock.h"
#include "bedrock/core/math/vec3.h"
#include "bedrock/server/commands/command_output.h"
#include "bedrock/server/commands/command_registry.h"

class CommandPosition {
public:
explicit CommandPosition(const Vec3 &);

private:
Vec3 offset_; // +0
bool relative_x_; // +12
bool relative_y_; // +13
bool relative_z_; // +14
bool local_; // +15
};

class CommandPositionFloat : public CommandPosition {};

class RelativeFloat {
public:
RelativeFloat() = default;
Expand All @@ -40,8 +55,8 @@ class Command {
virtual bool collectOptionalArguments();
virtual void execute(CommandOrigin const &, CommandOutput &) const = 0;

[[nodiscard]] std::string getCommandName() const;
void run(CommandOrigin const &origin, CommandOutput &output) const;
[[nodiscard]] std::string getCommandName() const;
void run(CommandOrigin const &origin, CommandOutput &output) const;

private:
int version_ = 0;
Expand Down
22 changes: 21 additions & 1 deletion src/bedrock/server/commands/command_origin.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "bedrock/deps/json/value.h"
#include "bedrock/network/network_identifier.h"
#include "bedrock/platform/uuid.h"
#include "bedrock/server/commands/command.h"
#include "bedrock/server/commands/command_origin_data.h"
#include "bedrock/server/commands/command_permission_level.h"
#include "bedrock/world/actor/player/abilities.h"
Expand Down Expand Up @@ -71,10 +72,29 @@ class CommandOrigin {
[[nodiscard]] virtual Vec3 getExecutePosition(int, const CommandPositionFloat &) const = 0; // 28
[[nodiscard]] virtual CompoundTag serialize() const = 0; // 29
[[nodiscard]] virtual bool isValid() const = 0; // 30
virtual void setUUID(const mce::UUID &uuid) = 0; // 31

protected:
virtual void _setUUID(const mce::UUID &uuid) = 0; // 31

public:
[[nodiscard]] std::shared_ptr<endstone::CommandSender> getEndstoneSender() const; // Endstone

protected:
mce::UUID uuid_;
};

class VirtualCommandOrigin : public CommandOrigin {
public:
VirtualCommandOrigin(const CommandOrigin &, const CommandOrigin &, const CommandPositionFloat &, int);
[[nodiscard]] CommandOrigin *getOrigin() const
{
return origin_.get();
}

private:
Vec3 pos_; // +24
std::unique_ptr<CommandOrigin> origin_; // +40
std::unique_ptr<CommandOrigin> output_receiver_; // +48
CommandPositionFloat command_position_; // +56
int version_; // +72
};
7 changes: 5 additions & 2 deletions src/bedrock/server/commands/command_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,23 @@
#include <optional>
#include <stack>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include <fmt/format.h>

#include "bedrock/bedrock.h"
#include "bedrock/core/utility/type_id.h"
#include "bedrock/network/packet/available_commands_packet.h"
#include "bedrock/server/commands/command_flag.h"
#include "bedrock/server/commands/command_origin.h"
#include "bedrock/server/commands/command_permission_level.h"
#include "bedrock/server/commands/command_version.h"

class Command;
class CommandRunStats;
class CommandOrigin;
class CommandParameterData;
class CommandRunStats;
enum class SemanticConstraint;

namespace endstone::core {
Expand Down
28 changes: 12 additions & 16 deletions src/endstone/core/command/command_sender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,40 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "bedrock/server/commands/command_origin.h"
#include "endstone/command/command_sender.h"

#include <entt/entt.hpp>

#include "bedrock/server/commands/command_origin.h"
#include "bedrock/server/commands/command_origin_loader.h"
#include "bedrock/world/actor/actor.h"
#include "bedrock/world/actor/player/player.h"
#include "endstone/command/command_sender.h"
#include "endstone/core/command/console_command_sender.h"
#include "endstone/core/level/level.h"
#include "endstone/core/command/proxied_command_sender.h"
#include "endstone/core/permissions/permissible.h"
#include "endstone/core/player.h"
#include "endstone/core/server.h"

using endstone::core::EndstoneActor;
using endstone::core::EndstoneConsoleCommandSender;
using endstone::core::EndstoneLevel;
using endstone::core::EndstonePlayer;
using endstone::core::EndstoneServer;

std::shared_ptr<endstone::CommandSender> CommandOrigin::getEndstoneSender() const
{
auto &server = entt::locator<EndstoneServer>::value();
auto &server = entt::locator<endstone::core::EndstoneServer>::value();
switch (getOriginType()) {
case CommandOriginType::DedicatedServer: {
return std::static_pointer_cast<endstone::ConsoleCommandSender>(
static_cast<EndstoneConsoleCommandSender &>(server.getCommandSender()).shared_from_this());
static_cast<endstone::core::EndstoneConsoleCommandSender &>(server.getCommandSender()).shared_from_this());
}
case CommandOriginType::Player:
case CommandOriginType::Entity: {
return std::static_pointer_cast<endstone::Actor>(getEntity()->getEndstoneActor().shared_from_this());
}
case CommandOriginType::Virtual:
// TODO(command): we need ProxiedCommandSender, getOrigin will return the callee, getOutputReceiver will return
// the caller
case CommandOriginType::Virtual: {
const auto &virtual_command_origin = *static_cast<const VirtualCommandOrigin *>(this);
return endstone::core::PermissibleFactory::create<endstone::core::EndstoneProxiedCommandSender>(
getOutputReceiver().getEndstoneSender(), virtual_command_origin.getOrigin()->getEndstoneSender());
}
case CommandOriginType::CommandBlock:
case CommandOriginType::MinecartCommandBlock:
// TODO(permission): add BlockCommandSender, Entity and CommandMinecart
default:
return nullptr;
}
}
}
9 changes: 5 additions & 4 deletions src/endstone/core/command/proxied_command_sender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@

namespace endstone::core {

EndstoneProxiedCommandSender::EndstoneProxiedCommandSender(CommandSender &caller, CommandSender &callee)
: caller_(caller), callee_(callee)
EndstoneProxiedCommandSender::EndstoneProxiedCommandSender(std::shared_ptr<CommandSender> caller,
std::shared_ptr<CommandSender> callee)
: caller_(std::move(caller)), callee_(std::move(callee))
{
}
bool EndstoneProxiedCommandSender::isOp() const
Expand Down Expand Up @@ -115,12 +116,12 @@ std::string EndstoneProxiedCommandSender::getName() const

CommandSender &EndstoneProxiedCommandSender::getCaller() const
{
return caller_;
return *caller_;
}

CommandSender &EndstoneProxiedCommandSender::getCallee() const
{
return callee_;
return *callee_;
}

} // namespace endstone::core
6 changes: 3 additions & 3 deletions src/endstone/core/command/proxied_command_sender.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace endstone::core {

class EndstoneProxiedCommandSender : public ProxiedCommandSender {
protected:
EndstoneProxiedCommandSender(CommandSender &caller, CommandSender &callee);
EndstoneProxiedCommandSender(std::shared_ptr<CommandSender> caller, std::shared_ptr<CommandSender> callee);

public:
[[nodiscard]] bool isOp() const override;
Expand All @@ -45,8 +45,8 @@ class EndstoneProxiedCommandSender : public ProxiedCommandSender {
[[nodiscard]] CommandSender &getCallee() const override;

private:
CommandSender &caller_;
CommandSender &callee_;
std::shared_ptr<CommandSender> caller_;
std::shared_ptr<CommandSender> callee_;
};

} // namespace endstone::core
6 changes: 6 additions & 0 deletions src/endstone/python/command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ void init_command(py::module &m, py::class_<CommandSender, Permissible> &command

py::class_<ConsoleCommandSender, CommandSender>(m, "ConsoleCommandSender", "Represents a console command sender.");

py::class_<ProxiedCommandSender, CommandSender>(m, "ProxiedCommandSender", "Represents a proxied command sender.")
.def_property_readonly("caller", &ProxiedCommandSender::getCaller, py::return_value_policy::reference,
"Returns the CommandSender which triggered this proxied command.")
.def_property_readonly("callee", &ProxiedCommandSender::getCallee, py::return_value_policy::reference,
"Returns the CommandSender which is being used to call the command.");

py::class_<Command, std::shared_ptr<Command>>(m, "Command",
"Represents a Command, which executes various tasks upon user input")
.def(py::init(&createCommand), py::arg("name"), py::arg("description") = py::none(),
Expand Down

0 comments on commit df567c9

Please sign in to comment.