Skip to content

Commit

Permalink
feat: add CommandOutput
Browse files Browse the repository at this point in the history
  • Loading branch information
wu-vincent committed Mar 4, 2024
1 parent 3eacc09 commit 5089524
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 9 deletions.
46 changes: 45 additions & 1 deletion include/bedrock/command/command_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,50 @@

#pragma once

class CommandOutput {};
#include <memory>
#include <string>
#include <vector>

#include "bedrock/bedrock.h"

enum class CommandOutputMessageType {
Success = 0,
Error = 1,
};

enum class CommandOutputType {
None = 0,
Message = 1,
Json = 4,
};

class CommandOutputMessage {
public:
CommandOutputMessageType type; // +0
std::string message_id; // +8
std::vector<std::string> params; // +40
};

class CommandOutputParameter {
public:
std::string text; // +0
int count; // +32 - the number of targets returned by selector (e.g. actor / player)
};

class CommandOutput {
public:
void success()
{
success_count++;
}
BEDROCK_API void forceOutput(const std::string &message_id, const std::vector<CommandOutputParameter> &params);
BEDROCK_API void error(const std::string &message_id, const std::vector<CommandOutputParameter> &params);

CommandOutputType type; // +0
std::unique_ptr<class CommandPropertyBag> data; // +8
std::vector<CommandOutputMessage> messages; // +16
int success_count; // +40
bool has_player_text; // +44
};

class CommandOutputSender {};
2 changes: 1 addition & 1 deletion include/endstone/command/command_executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class CommandExecutor {
virtual ~CommandExecutor() = default;

/**
* Executes the given command, returning its success.
* Executes the given command, returning its forceOutput.
*
* @param sender Source of the command
* @param command Command which was executed
Expand Down
13 changes: 13 additions & 0 deletions include/endstone/command/command_sender.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ class CommandSender {
sendMessage(fmt::format(format, std::forward<Args>(args)...));
}

/**
* Sends this sender a error message
*
* @param message Error message to be displayed
*/
virtual void sendErrorMessage(const std::string &message) const = 0;

template <typename... Args>
void sendErrorMessage(const fmt::format_string<Args...> format, Args &&...args) const
{
sendErrorMessage(fmt::format(format, std::forward<Args>(args)...));
}

/**
* Returns the server instance that this command is running on
*
Expand Down
1 change: 1 addition & 0 deletions include/endstone/detail/command/command_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class CommandSenderAdapter : public CommandSender {
public:
CommandSenderAdapter(EndstoneServer &server, const CommandOrigin &origin, CommandOutput &output);
void sendMessage(const std::string &message) const override;
void sendErrorMessage(const std::string &message) const override;
[[nodiscard]] Server &getServer() const override;
[[nodiscard]] std::string getName() const override;

Expand Down
19 changes: 12 additions & 7 deletions src/endstone_core/command/command_adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ CommandSenderAdapter::CommandSenderAdapter(EndstoneServer &server, const Command

void CommandSenderAdapter::sendMessage(const std::string &message) const
{
// TODO: addMessage to output
printf("%s\n", message.c_str());
printf("Sender name: %s\n", getName().c_str());
output_.forceOutput(message, {});
}

void CommandSenderAdapter::sendErrorMessage(const std::string &message) const
{
output_.error(message, {});
}

Server &CommandSenderAdapter::getServer() const
Expand All @@ -40,17 +43,19 @@ std::string CommandSenderAdapter::getName() const
void CommandAdapter::execute(const CommandOrigin &origin, CommandOutput &output) const
{
auto &server = Singleton<EndstoneServer>::getInstance();
auto sender = CommandSenderAdapter(server, origin, output);

auto &command_map = server.getCommandMap();
auto command_name = getCommandName();
auto *command = command_map.getCommand(getCommandName());
if (command) {
auto sender = CommandSenderAdapter(server, origin, output);
bool success = command->execute(sender, {});
if (!success) {
// TODO: set output status code
if (success) {
output.success();
}
}
else {
// TODO: shouldn't happen, what to do now? be silent or print error message?
sender.CommandSender::sendErrorMessage("Command {} was executed but not registered.", command_name);
}
}

Expand Down
27 changes: 27 additions & 0 deletions src/endstone_runtime/bedrock/command_output.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2024, The Endstone Project. (https://endstone.dev) All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "bedrock/command/command_output.h"

#include "endstone/detail/hook.h"

void CommandOutput::forceOutput(const std::string &message_id, const std::vector<CommandOutputParameter> &params)
{
ENDSTONE_HOOK_CALL_ORIGINAL(&CommandOutput::forceOutput, this, message_id, params);
}

void CommandOutput::error(const std::string &message_id, const std::vector<CommandOutputParameter> &params)
{
ENDSTONE_HOOK_CALL_ORIGINAL(&CommandOutput::error, this, message_id, params);
}

0 comments on commit 5089524

Please sign in to comment.