diff --git a/mods/include/mods/api/api.h b/mods/include/mods/api/api.h new file mode 100644 index 00000000..b436b13c --- /dev/null +++ b/mods/include/mods/api/api.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +#include + +void api_add_chat_event(Entity *sender, const std::string &message); + diff --git a/mods/include/mods/chat/chat.h b/mods/include/mods/chat/chat.h index f80ea70a..361da41c 100644 --- a/mods/include/mods/chat/chat.h +++ b/mods/include/mods/chat/chat.h @@ -12,8 +12,6 @@ std::string chat_send_api_command(const Minecraft *minecraft, const std::string // Override using the HOOK() macro to provide customized chat behavior. void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, Entity *sender, const char *message); void chat_handle_packet_send(const Minecraft *minecraft, ChatPacket *packet); -void chat_set_already_added(bool already_added); -bool chat_already_added(); bool chat_is_sending(); } diff --git a/mods/include/mods/misc/misc.h b/mods/include/mods/misc/misc.h index e84b346b..c54ab70f 100644 --- a/mods/include/mods/misc/misc.h +++ b/mods/include/mods/misc/misc.h @@ -30,10 +30,9 @@ void misc_run_on_swap_buffers(const std::function &function); std::string misc_get_player_username(Player *player); std::map &misc_get_entity_names(); std::string misc_get_entity_type_name(Entity *entity); -std::string misc_get_entity_name(Entity *entity, bool convert_to_utf = false); -std::string misc_get_entity_name_upper(Entity *entity, bool convert_to_utf = false); +std::string misc_get_entity_name(Entity *entity); +std::string misc_get_entity_name_upper(Entity *entity); Entity *misc_make_entity_from_id(Level *level, int id); -void api_add_chat_event(Entity *sender, const std::string &message); std::string misc_base64_encode(const std::string &data); std::string misc_base64_decode(const std::string &input); diff --git a/mods/src/api/api.cpp b/mods/src/api/api.cpp index 88e39bb9..776cc52c 100644 --- a/mods/src/api/api.cpp +++ b/mods/src/api/api.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -14,6 +15,21 @@ #include static bool compat_mode = true; +static std::string get_input(std::string message) { + return to_cp437(compat_mode ? message.c_str() : misc_base64_decode(message).c_str()); +} +static std::string get_output(std::string message, bool replace = true, bool replace_comma = false) { + if (replace) { + if (compat_mode) { + std::replace(message.begin(), message.end(), '|', '\\'); + if (replace_comma) { + std::replace(message.begin(), message.end(), ',', '.'); + } + } else message = misc_base64_encode(message); + } + return from_cp437(message.c_str()); +} + static std::string getBlocks(CommandServer *commandserver, Vec3 start, Vec3 end) { int startx = start.x, starty = start.y, startz = start.z; int endx = end.x, endy = end.y, endz = end.z; @@ -72,7 +88,7 @@ static std::string getEntityData(CommandServer *commandserver, Entity *entity) { // type std::to_string(entity->getEntityTypeId()) + "," + // name - empty_fallback(misc_get_entity_name_upper(entity, true), entity->id) + "," + + empty_fallback(get_output(misc_get_entity_name_upper(entity), true, true), entity->id) + "," + // x std::to_string(x) + "," + // y @@ -207,16 +223,14 @@ static std::string getBlockHits(CommandServer *commandserver, ConnectedClient &c } template -static std::string getEventsOfId(CircularQueue events, CommandServer *commandserver, int id) { +static std::string getEventsOfId(CircularQueue &events, CommandServer *commandserver, int id) { std::string ret = ""; int i = events.start; while (events.at != i) { T event = events.buf[i]; - if (event.owner_id == id && !event.invalid) { + if (event.owner_id == id && event.invalid == false) { events.buf[i].invalid = true; - std::string message = event.toString(commandserver); - if (compat_mode) std::replace(message.begin(), message.end(), '|', '\\'); - else message = misc_base64_encode(message); + std::string message = get_output(event.toString(commandserver)); ret += message + "|"; } events.advance_counter(i); @@ -287,7 +301,7 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ if (entity == NULL) { WARN("Player (or Entity) [%i] not found in entity.getName.", id); } - return empty_fallback(misc_get_entity_name_upper(entity, true), entity->id) + "\n"; + return empty_fallback(get_output(misc_get_entity_name_upper(entity)), entity->id) + "\n"; } else if (cmd == "world.getEntities") { int type; int ret = sscanf(args.c_str(), "%d", &type); @@ -332,9 +346,7 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ while (chatEvents.at != chatEvents.start) { ChatEvent ce = chatEvents.pop(); if (!ce.invalid) { - std::string message = ce.toString(commandserver); - if (compat_mode) std::replace(message.begin(), message.end(), '|', '\\'); - else message = misc_base64_encode(message); + std::string message = get_output(ce.toString(commandserver)); ret += message + "|"; } } @@ -487,10 +499,12 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ if (ret == 3) return ""; SignTileEntity *sign = (SignTileEntity *) commandserver->minecraft->level->getTileEntity(x, y, z); if (sign == NULL || sign->type != 4) return ""; - if (ret > 5) sign->lines[0] = compat_mode ? l1 : misc_base64_decode(l1); - if (ret > 6) sign->lines[1] = compat_mode ? l2 : misc_base64_decode(l2); - if (ret > 7) sign->lines[2] = compat_mode ? l3 : misc_base64_decode(l3); - if (ret > 8) sign->lines[3] = compat_mode ? l4 : misc_base64_decode(l4); + char *lines[4] = {l1, l2, l3, l4}; + for (int i = 0; i < 4; i++) { + if (ret > i + 5) { + sign->lines[i] = get_input(lines[i]); + } + } } else if (cmd == "world.spawnEntity") { // Parse float x, y, z; @@ -629,14 +643,10 @@ static void Throwable_tick_Throwable_onHit_injection(Throwable *self, HitResult static void Gui_addMessage_injection(Gui_addMessage_t original, Gui *gui, const std::string &text) { static bool recursing = false; - if (recursing || chat_already_added()) { - chat_set_already_added(false); + if (recursing) { original(gui, text); } else { - if (chat_is_sending()) { - std::string message = text.substr(gui->minecraft->player->username.size() + 3); - api_add_chat_event((Entity *) gui->minecraft->player, text); - } else { + if (!chat_is_sending()) { api_add_chat_event(NULL, text); } recursing = true; diff --git a/mods/src/chat/chat.cpp b/mods/src/chat/chat.cpp index dc6e51f2..1b9b3c1c 100644 --- a/mods/src/chat/chat.cpp +++ b/mods/src/chat/chat.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include "chat-internal.h" @@ -35,17 +35,14 @@ static void send_api_chat_command(const Minecraft *minecraft, const char *str) { std::string _chat_get_prefix(const char *username) { return std::string("<") + username + "> "; } -static bool _chat_already_added = false; -bool chat_already_added() { - return _chat_already_added; -} -void chat_set_already_added(bool already_added) { - _chat_already_added = already_added; +static bool _chat_is_sending = false; +bool chat_is_sending() { + return _chat_is_sending; } void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, Entity *sender, const char *message) { const char *username = NULL; if (sender && sender->isPlayer()) { - _chat_already_added = true; + _chat_is_sending = true; api_add_chat_event(sender, message); username = ((Player *) sender)->username.c_str(); } else { @@ -58,6 +55,7 @@ void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, En full_message = raw_str; free(raw_str); server_side_network_handler->displayGameMessage(full_message); + _chat_is_sending = false; } // Handle Chat packet Send void chat_handle_packet_send(const Minecraft *minecraft, ChatPacket *packet) { @@ -66,7 +64,7 @@ void chat_handle_packet_send(const Minecraft *minecraft, ChatPacket *packet) { // Hosting Multiplayer const char *message = packet->message.c_str(); ServerSideNetworkHandler *server_side_network_handler = (ServerSideNetworkHandler *) minecraft->network_handler; - chat_send_message(server_side_network_handler, NULL, (char *) message); + chat_send_message(server_side_network_handler, (Entity *) minecraft->player, (char *) message); } else { // Client rak_net_instance->send(*(Packet *) packet); @@ -91,14 +89,8 @@ static void ServerSideNetworkHandler_handle_ChatPacket_injection(ServerSideNetwo } // Send Message -static bool _chat_is_sending = false; -bool chat_is_sending() { - return _chat_is_sending; -} void _chat_send_message(const Minecraft *minecraft, const char *message) { - _chat_is_sending = true; send_api_chat_command(minecraft, message); - _chat_is_sending = false; } // Allow Reading Longer ChatPacket Messages diff --git a/mods/src/misc/api.cpp b/mods/src/misc/api.cpp index 601cc7ee..c6e7c9ae 100644 --- a/mods/src/misc/api.cpp +++ b/mods/src/misc/api.cpp @@ -158,14 +158,14 @@ std::map &misc_get_entity_names() { }; -std::string misc_get_entity_name(Entity *entity, bool convert_to_utf) { +std::string misc_get_entity_name(Entity *entity) { if (!entity) return ""; - if (entity->isPlayer()) return convert_to_utf ? misc_get_player_username((Player *) entity) : ((Player *) entity)->username; + if (entity->isPlayer()) return ((Player *) entity)->username; return misc_get_entity_type_name(entity); } -std::string misc_get_entity_name_upper(Entity *entity, bool convert_to_utf) { - std::string ret = misc_get_entity_name(entity, convert_to_utf); +std::string misc_get_entity_name_upper(Entity *entity) { + std::string ret = misc_get_entity_name(entity); if (entity != NULL && !entity->isPlayer()) { for (char &c : ret) c = toupper(c); } @@ -179,9 +179,11 @@ std::string misc_get_entity_type_name(Entity *entity) { return "Player"; } else { int type = entity->getEntityTypeId(); - if (type == 0 && entity->vtable == (Entity_vtable *) Particle_vtable_base) return "Particle"; - if (type == 0 && entity->vtable == (Entity_vtable *) TripodCamera_vtable_base) return "TripodCamera"; - if (type == 0 && entity->vtable == (Entity_vtable *) CameraEntity_vtable_base) return "CameraEntity"; + if (type == 0) { + if (entity->vtable == (Entity_vtable *) Particle_vtable_base) return "Particle"; + if (entity->vtable == (Entity_vtable *) TripodCamera_vtable_base) return "TripodCamera"; + if (entity->vtable == (Entity_vtable *) CameraEntity_vtable_base) return "CameraEntity"; + } std::map &names = misc_get_entity_names(); if (names.find(type) != names.end()) return names[type]; return "";