summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Chat.cpp146
-rw-r--r--src/Chat.hpp90
-rw-r--r--src/GameState.cpp2
-rw-r--r--src/Packet.hpp6
-rw-r--r--src/Render.cpp2
5 files changed, 206 insertions, 40 deletions
diff --git a/src/Chat.cpp b/src/Chat.cpp
index 193c1fd..6870a83 100644
--- a/src/Chat.cpp
+++ b/src/Chat.cpp
@@ -4,29 +4,135 @@
using nlohmann::json;
-void Recursive(const json::iterator &iter, bool isIterObj, std::string &str) {
- if (isIterObj && iter.key() == "text") {
- str.append(iter->get<std::string>() + " ");
- }
-
- if (iter->is_structured()) {
- for (json::iterator it = iter->begin(); it != iter->end(); ++it)
- Recursive(it, iter->is_object(), str);
- }
+Component RecurParseComponent(json j) {
+ Component component;
+ if (j.is_string()) {
+ component.type = Component::STRING;
+ component.text = j.get<std::string>();
+ return component;
+ }
+
+ if (j.find("text") != j.end()) {
+ component.type = Component::STRING;
+ component.text = j["text"].get<std::string>();
+ }
+ else if (j.find("translate") != j.end()) {
+ component.type = Component::TRANSLATION;
+ component.translate = j["translate"].get<std::string>();
+ for (auto& it : j["with"]) {
+ component.with.push_back(RecurParseComponent(it));
+ }
+ }
+ else if (j.find("keybind") != j.end()) {
+
+ }
+ else if (j.find("score") != j.end()) {
+
+ }
+ else if (j.find("selector") != j.end()) {
+
+ }
+
+ if (j.find("bold") != j.end())
+ component.isBold = j["bold"].get<bool>();
+ if (j.find("italic") != j.end())
+ component.isItalic = j["italic"].get<bool>();
+ if (j.find("underlined") != j.end())
+ component.isUnderlined = j["underlined"].get<bool>();
+ if (j.find("strikethrough") != j.end())
+ component.isStrikethrough = j["strikethrough"].get<bool>();
+ if (j.find("obfuscated") != j.end())
+ component.isObfuscated = j["obfuscated"].get<bool>();
+ if (j.find("color") != j.end())
+ component.color = j["color"].get<std::string>();
+ if (j.find("insertion") != j.end())
+ component.insertion = j["insertion"].get<std::string>();
+
+ if (j.find("clickEvent") != j.end()) {
+ component.clickEvent.value = j["clickEvent"]["value"].get<std::string>();
+
+ if (j["clickEvent"]["action"] == "open_url")
+ component.clickEvent.action = ClickEvent::OPEN_URL;
+ else if (j["clickEvent"]["action"] == "open_file")
+ component.clickEvent.action = ClickEvent::OPEN_FILE;
+ else if (j["clickEvent"]["action"] == "run_command")
+ component.clickEvent.action = ClickEvent::RUN_COMMAND;
+ else if (j["clickEvent"]["action"] == "suggest_command")
+ component.clickEvent.action = ClickEvent::SUGGEST_COMMAND;
+ else if (j["clickEvent"]["action"] == "change_page")
+ component.clickEvent.action = ClickEvent::CHANGE_PAGE;
+ }
+
+ if (j.find("hoverEvent") != j.end()) {
+ if (j["hoverEvent"]["value"].is_string())
+ component.hoverEvent.value = j["hoverEvent"]["value"].get<std::string>();
+ else
+ component.hoverEvent.value = j["hoverEvent"]["value"]["text"].get<std::string>();
+
+ if (j["hoverEvent"]["action"] == "show_text")
+ component.hoverEvent.action = HoverEvent::SHOW_TEXT;
+ else if (j["hoverEvent"]["action"] == "show_item")
+ component.hoverEvent.action = HoverEvent::SHOW_ITEM;
+ else if (j["hoverEvent"]["action"] == "show_entity")
+ component.hoverEvent.action = HoverEvent::SHOW_ENTITY;
+ else if (j["hoverEvent"]["action"] == "show_achievement")
+ component.hoverEvent.action = HoverEvent::SHOW_ACHIEVEMENT;
+ }
+
+ if (j.find("extra") != j.end()) {
+ for (auto& it : j["extra"]) {
+ component.extra.push_back(RecurParseComponent(it));
+ }
+ }
+
+ return component;
+}
+
+Chat::Chat(const std::string &json) {
+ static const size_t s = sizeof(Component);
+ nlohmann::json j = nlohmann::json::parse(json);
+ volatile size_t f = s + 1;
+ component = RecurParseComponent(j);
}
-Chat::Chat(const std::string &str) {
- json j = json::parse(str);
+void RecurPlainTextAppend(const Component& component, std::string& str) {
+ switch (component.type) {
+ case Component::STRING:
+ str += component.text;
+ break;
+ case Component::TRANSLATION:
+ if (component.translate == "chat.type.text") {
+ str += "<";
+ RecurPlainTextAppend(component.with[0], str);
+ str += "> ";
+ for (int i = 1; i < component.with.size(); i++)
+ RecurPlainTextAppend(component.with[i], str);
+ } else {
+ str += component.translate;
+ str += "{";
+ for (auto& it : component.with) {
+ RecurPlainTextAppend(it, str);
+ str += ";";
+ }
+ str += "}";
+ }
+ break;
+ default:
+ break;
+ }
+
+ for (auto& it : component.extra) {
+ RecurPlainTextAppend(it, str);
+ }
+}
- if (j["translate"] == "chat.type.text") {
- text = j["with"][0]["text"].get<std::string>() + ": " + j["with"][1].get<std::string>();
- } else
- for (json::iterator it = j.begin(); it != j.end(); ++it) {
- Recursive(it, j.is_object(), text);
- }
+std::string Chat::ToPlainText() const
+{
+ std::string ret;
+ RecurPlainTextAppend(component, ret);
+ return ret;
}
std::string Chat::ToJson() const {
- throw std::logic_error("Chat not deserealizable");
- return text;
-} \ No newline at end of file
+ return "";
+}
diff --git a/src/Chat.hpp b/src/Chat.hpp
index 9ab5691..f9dde98 100644
--- a/src/Chat.hpp
+++ b/src/Chat.hpp
@@ -3,23 +3,83 @@
#include <vector>
#include <string>
-struct TextModifier {
- size_t offset;
- size_t length;
- enum {
- Italic,
- Bold,
- Underline,
- } type;
+
+struct ClickEvent {
+ enum ActionType {
+ NONE,
+ OPEN_URL,
+ OPEN_FILE,
+ RUN_COMMAND,
+ SUGGEST_COMMAND,
+ CHANGE_PAGE,
+ } action = NONE;
+ std::string value;
+};
+
+struct HoverEvent {
+ enum ActionType {
+ NONE,
+ SHOW_TEXT,
+ SHOW_ITEM,
+ SHOW_ENTITY,
+ SHOW_ACHIEVEMENT,
+ } action = NONE;
+ std::string value;
};
-struct Chat {
- std::vector<TextModifier> modifiers;
- std::string text;
+struct Component {
+ enum ComponentType {
+ DEFAULT,
+ STRING,
+ TRANSLATION,
+ KEYBIND,
+ SCORE,
+ SELECTOR,
+ UNKNOWN,
+ } type = DEFAULT;
+
+ bool isBold = false;
+ bool isItalic = false;
+ bool isUnderlined = false;
+ bool isStrikethrough = false;
+ bool isObfuscated = false;
+ std::string color;
+ std::string insertion;
+ ClickEvent clickEvent;
+ HoverEvent hoverEvent;
+ std::vector<Component> extra;
+
+ //string component
+ std::string text;
- Chat(const std::string &str);
+ //tranlation component
+ std::string translate;
+ std::vector<Component> with;
- Chat() = default;
+ //keybind component
+ std::string keybind;
+
+ //score component
+ struct {
+ std::string name;
+ std::string objective;
+ std::string value;
+ } score;
+
+ //selector component
+ std::string selector;
+};
- std::string ToJson() const;
-}; \ No newline at end of file
+class Chat {
+ Component component;
+
+public:
+
+ Chat() = default;
+
+ Chat(const std::string &json);
+
+ std::string ToPlainText() const;
+
+ std::string ToJson() const;
+};
diff --git a/src/GameState.cpp b/src/GameState.cpp
index 8e50ee6..fdb453f 100644
--- a/src/GameState.cpp
+++ b/src/GameState.cpp
@@ -150,7 +150,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) {
case ChatMessageCB: {
auto packet = std::static_pointer_cast<PacketChatMessageCB>(ptr);
- LOG(INFO) << "Message (" << int(packet->Position) << "): " << packet->JsonData.text;
+ LOG(INFO) << "Message (" << int(packet->Position) << "): " << packet->JsonData.ToPlainText();
PUSH_EVENT("ChatMessageReceived", std::make_tuple(packet->JsonData, packet->Position));
break;
}
diff --git a/src/Packet.hpp b/src/Packet.hpp
index 275de75..cca01ec 100644
--- a/src/Packet.hpp
+++ b/src/Packet.hpp
@@ -241,7 +241,7 @@ struct PacketDisconnectPlay : Packet {
}
void FromStream(StreamInput *stream) override {
- Reason = stream->ReadChat().text;
+ Reason = stream->ReadChat().ToPlainText();
}
int GetPacketId() override {
@@ -861,7 +861,7 @@ struct PacketOpenWindow : Packet {
void FromStream(StreamInput *stream) override {
WindowId = stream->ReadUByte();
WindowType = stream->ReadString();
- WindowTitle = stream->ReadChat().text;
+ WindowTitle = stream->ReadChat().ToPlainText();
NumberOfSlots = stream->ReadUByte();
if (WindowType == "EntityHorse")
@@ -1032,7 +1032,7 @@ struct PacketDisconnect : Packet {
}
void FromStream(StreamInput *stream) override {
- Reason = stream->ReadChat().text;
+ Reason = stream->ReadChat().ToPlainText();
}
int GetPacketId() override {
diff --git a/src/Render.cpp b/src/Render.cpp
index 128c877..d583205 100644
--- a/src/Render.cpp
+++ b/src/Render.cpp
@@ -713,7 +713,7 @@ void Render::InitEvents() {
listener.RegisterHandler("ChatMessageReceived", [this](const Event& eventData) {
auto data = eventData.get<std::tuple<Chat, unsigned char>>();
- std::string msg = "(" + std::to_string((int)std::get<1>(data)) + ") " + std::get<0>(data).text;
+ std::string msg = "(" + std::to_string((int)std::get<1>(data)) + ") " + (std::get<0>(data).ToPlainText());
chatMessages.push_back(msg);
});