Skip to content

Commit

Permalink
📚 Improved chat message
Browse files Browse the repository at this point in the history
  • Loading branch information
Lygaen committed Feb 11, 2024
1 parent f6be0c6 commit 861fb8d
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 17 deletions.
125 changes: 110 additions & 15 deletions src/types/chatmessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ void ChatMessage::load(const rapidjson::Value &document)
LS(insertion);
LS(text);

clickEvent.load(document);

if ((it = document.FindMember("extra")) != document.MemberEnd() &&
it->value.IsArray())
{
Expand All @@ -104,6 +106,7 @@ void ChatMessage::save(rapidjson::Value &document, rapidjson::Document::Allocato
WV(underlined);
WV(strikethrough);
WV(obfuscated);
#undef WV

#define WS(x) \
if (x.size() != 0) \
Expand All @@ -113,6 +116,10 @@ void ChatMessage::save(rapidjson::Value &document, rapidjson::Document::Allocato
WS(insertion);
WS(text);

#undef WS

clickEvent.save(document, alloc);

if (next == nullptr)
return;
ChatMessage *n = next;
Expand All @@ -137,19 +144,107 @@ bool operator==(const ChatMessage &lhs, const ChatMessage &rhs)

void ChatMessage::loadLua(lua_State *state, const char *namespaceName) {
luabridge::getGlobalNamespace(state)
.beginNamespace(namespaceName)
.beginClass<ChatMessage>("ChatMessage")
.addConstructor([](void* ptr) {return new (ptr) ChatMessage();},
[](void* ptr, const std::string &msg) {return new (ptr) ChatMessage(msg);})
.addProperty("bold", &ChatMessage::bold)
.addProperty("italic", &ChatMessage::italic)
.addProperty("underlined", &ChatMessage::underlined)
.addProperty("strikethrough", &ChatMessage::strikethrough)
.addProperty("obfuscated", &ChatMessage::obfuscated)
.addProperty("color", &ChatMessage::color)
.addProperty("insertion", &ChatMessage::insertion)
.addProperty("text", &ChatMessage::text)
.addFunction("addExtra", &ChatMessage::addExtra)
.endClass()
.endNamespace();
.beginNamespace(namespaceName)
.beginClass<ChatMessage>("ChatMessage")
.addConstructor([](void *ptr)
{ return new (ptr) ChatMessage(); },
[](void *ptr, const std::string &msg)
{ return new (ptr) ChatMessage(msg); })
.addProperty("bold", &ChatMessage::bold)
.addProperty("italic", &ChatMessage::italic)
.addProperty("underlined", &ChatMessage::underlined)
.addProperty("strikethrough", &ChatMessage::strikethrough)
.addProperty("obfuscated", &ChatMessage::obfuscated)
.addProperty("color", &ChatMessage::color)
.addProperty("insertion", &ChatMessage::insertion)
.addProperty("text", &ChatMessage::text)
.addFunction("addExtra", &ChatMessage::addExtra)
.addProperty("clickEvent", &ChatMessage::clickEvent)
.endClass()
.endNamespace();

ClickEvent::loadLua(state, namespaceName);
}

ChatMessage::ClickEvent::ClickEvent(ActionType action, const std::string &value)
: action(action), value(value)
{
}

ChatMessage::ClickEvent::ClickEvent(uint changePage)
: action(ActionType::CHANGE_PAGE), value(std::to_string(changePage))
{
}

ChatMessage::ClickEvent::ClickEvent() : action(ActionType::NONE)
{
}

const std::unordered_map<std::string, ChatMessage::ClickEvent::ActionType> ACTION_TABLE{
{"open_url", ChatMessage::ClickEvent::OPEN_URL},
{"run_command", ChatMessage::ClickEvent::RUN_COMMAND},
{"suggest_command", ChatMessage::ClickEvent::SUGGEST_COMMAND},
{"change_page", ChatMessage::ClickEvent::CHANGE_PAGE},
{"copy_to_clipboard", ChatMessage::ClickEvent::COPY_TO_CLIPBOARD},
};

void ChatMessage::ClickEvent::load(const rapidjson::Value &document)
{
rapidjson::Document::ConstMemberIterator it;
if ((it = document.FindMember("clickEvent")) == document.MemberEnd() ||
!it->value.IsObject())
return;
const rapidjson::Value &clickEvent = it->value;

if ((it = clickEvent.FindMember("action")) == document.MemberEnd() ||
!it->value.IsString())
return;
std::string stringAction(it->value.GetString(), it->value.GetStringLength());

if ((it = clickEvent.FindMember("value")) == document.MemberEnd() ||
!it->value.IsString())
return;
value = std::string(it->value.GetString(), it->value.GetStringLength());

if (!ACTION_TABLE.contains(stringAction))
{
action = ActionType::NONE;
value = "";
return;
}

action = ACTION_TABLE.at(stringAction);
}

void ChatMessage::ClickEvent::save(rapidjson::Value &document, rapidjson::Document::AllocatorType &alloc) const
{
if (action == ActionType::NONE)
return;

rapidjson::Value clickEvent(rapidjson::kObjectType);
auto it = std::find_if(std::begin(ACTION_TABLE), std::end(ACTION_TABLE),
[this](auto &&p)
{ return std::get<1>(p) == action; });
if (it == std::end(ACTION_TABLE))
throw std::runtime_error("Could not parse action !");

std::string stringAction = it->first;

clickEvent.AddMember("action", rapidjson::Value(stringAction.c_str(), stringAction.length(), alloc), alloc);
clickEvent.AddMember("value", rapidjson::Value(value.c_str(), value.length(), alloc), alloc);

document.AddMember("clickEvent", clickEvent, alloc);
}

void ChatMessage::ClickEvent::loadLua(lua_State *state, const char *namespaceName)
{
luabridge::getGlobalNamespace(state)
.beginNamespace(namespaceName)
.beginNamespace("ChatMessage")
.beginClass<ChatMessage::ClickEvent>("ClickEvent")
.addProperty("action", &ClickEvent::action)
.addProperty("value", &ClickEvent::value)
.endClass()
.endNamespace()
.endNamespace();
}
126 changes: 125 additions & 1 deletion src/types/chatmessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define MINESERVER_CHATMESSAGE_H

#include <string>
#include <unordered_map>
#include <rapidjson/rapidjson.h>
#include <rapidjson/document.h>
#include <plugins/luaheaders.h>
Expand Down Expand Up @@ -72,13 +73,124 @@ class ChatMessage
std::string insertion{};

/**
* @brief The (limited) text
* @brief The text excluding extras
*
* Does not parse for additional string components,
* only text.
*/
std::string text{};

/**
* @brief Click Event
*
* On message click event
*/
class ClickEvent
{
public:
/**
* @brief Type of action to perform
*
*/
enum ActionType
{
/**
* @brief No action
*
* Click event will not be saved to JSON.
*/
NONE,
/**
* @brief Open URL
*
*/
OPEN_URL,
/**
* @brief Run command
*
*/
RUN_COMMAND,
/**
* @brief Suggest command to user
*
*/
SUGGEST_COMMAND,
/**
* @brief Change page (book only)
*
*/
CHANGE_PAGE,
/**
* @brief Copy text to clipboard
*
*/
COPY_TO_CLIPBOARD
};

/**
* @brief Action to perform
*
*/
ActionType action;
/**
* @brief Value of action
*
*/
std::string value;

/**
* @brief Construct a new Click Event object
*
* @param action the action type
* @param value the value of action
*/
ClickEvent(ActionType action, const std::string &value);
/**
* @brief Construct a new Click Event object
*
* @param changePage see ActionType::CHANGE_PAGE
*/
ClickEvent(uint changePage);
/**
* @brief Construct a new Click Event object
*
*/
ClickEvent();
/**
* @brief Destroy the Click Event object
*
*/
~ClickEvent() = default;

/**
* @brief Load click event from JSON
*
* @param document the document to load from
*/
void load(const rapidjson::Value &document);
/**
* @brief Save click event to JSON
*
* @param document the document to save to
* @param alloc the document allocator
*/
void save(rapidjson::Value &document, rapidjson::Document::AllocatorType &alloc) const;

/**
* @brief Loads Click Event to lua
*
* @param state the state of lua
* @param namespaceName the namespace name
*/
static void loadLua(lua_State *state, const char *namespaceName);
};

/**
* @brief Click event for message
*
*/
ClickEvent clickEvent;

private:
ChatMessage *next = nullptr;

Expand Down Expand Up @@ -148,4 +260,16 @@ class ChatMessage
static void loadLua(lua_State *state, const char *namespaceName);
};

template <>
struct luabridge::Stack<ChatMessage::ClickEvent::ActionType>
: luabridge::Enum<ChatMessage::ClickEvent::ActionType,
ChatMessage::ClickEvent::ActionType::NONE,
ChatMessage::ClickEvent::ActionType::OPEN_URL,
ChatMessage::ClickEvent::ActionType::RUN_COMMAND,
ChatMessage::ClickEvent::ActionType::SUGGEST_COMMAND,
ChatMessage::ClickEvent::ActionType::CHANGE_PAGE,
ChatMessage::ClickEvent::ActionType::COPY_TO_CLIPBOARD>
{
};

#endif // MINESERVER_CHATMESSAGE_H
2 changes: 1 addition & 1 deletion src/utils/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void Field<ChatMessage>::load(const rapidjson::Document &document)
if (loc == document.MemberEnd())
return;

if (!loc->value.IsInt())
if (!loc->value.IsObject())
return;

value = ChatMessage();
Expand Down

0 comments on commit 861fb8d

Please sign in to comment.