Simplify MP chat code

This commit is contained in:
Bigjango13 2024-10-30 16:54:31 -07:00
parent ae359de188
commit c8840ff214
6 changed files with 56 additions and 47 deletions

View File

@ -0,0 +1,8 @@
#pragma once
#include <string>
#include <symbols/minecraft.h>
void api_add_chat_event(Entity *sender, const std::string &message);

View File

@ -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();
}

View File

@ -30,10 +30,9 @@ void misc_run_on_swap_buffers(const std::function<void()> &function);
std::string misc_get_player_username(Player *player);
std::map<int, std::string> &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);

View File

@ -7,6 +7,7 @@
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/api/api.h>
#include <mods/init/init.h>
#include <mods/misc/misc.h>
#include <mods/chat/chat.h>
@ -14,6 +15,21 @@
#include <mods/feature/feature.h>
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<typename T>
static std::string getEventsOfId(CircularQueue<T> events, CommandServer *commandserver, int id) {
static std::string getEventsOfId(CircularQueue<T> &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;

View File

@ -5,7 +5,7 @@
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/misc/misc.h>
#include <mods/api/api.h>
#include <mods/init/init.h>
#include <mods/feature/feature.h>
#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

View File

@ -158,14 +158,14 @@ std::map<int, std::string> &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<int, std::string> &names = misc_get_entity_names();
if (names.find(type) != names.end()) return names[type];
return "";