Make polling chat work in MP
This commit is contained in:
parent
c93f6f87bc
commit
5c264736de
@ -10,8 +10,10 @@ extern "C" {
|
||||
std::string chat_send_api_command(const Minecraft *minecraft, const std::string &str);
|
||||
|
||||
// Override using the HOOK() macro to provide customized chat behavior.
|
||||
void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, const char *username, const char *message);
|
||||
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();
|
||||
|
||||
}
|
||||
|
@ -27,11 +27,13 @@ void misc_run_on_game_key_press(const std::function<bool(Minecraft *, int)> &fun
|
||||
void misc_run_on_key_press(const std::function<bool(Minecraft *, int)> &func);
|
||||
void misc_run_on_creative_inventory_setup(const std::function<void(FillingContainer *)> &function);
|
||||
void misc_run_on_swap_buffers(const std::function<void()> &function);
|
||||
std::string misc_get_player_username(Player *player, bool convert_to_utf = false);
|
||||
std::string misc_get_player_username(Player *player);
|
||||
std::map<int, std::string> &misc_get_entity_names();
|
||||
std::string misc_get_entity_name(Entity *entity);
|
||||
std::string misc_get_entity_name_upper(Entity *entity);
|
||||
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);
|
||||
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);
|
||||
|
@ -72,7 +72,7 @@ static std::string getEntityData(CommandServer *commandserver, Entity *entity) {
|
||||
// type
|
||||
std::to_string(entity->getEntityTypeId()) + "," +
|
||||
// name
|
||||
empty_fallback(misc_get_entity_name_upper(entity), entity->id) + "," +
|
||||
empty_fallback(misc_get_entity_name_upper(entity, true), entity->id) + "," +
|
||||
// x
|
||||
std::to_string(x) + "," +
|
||||
// y
|
||||
@ -278,7 +278,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), entity->id) + "\n";
|
||||
return empty_fallback(misc_get_entity_name_upper(entity, true), entity->id) + "\n";
|
||||
} else if (cmd == "world.getEntities") {
|
||||
int type;
|
||||
int ret = sscanf(args.c_str(), "%d", &type);
|
||||
@ -661,21 +661,31 @@ 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) {
|
||||
if (recursing || chat_already_added()) {
|
||||
chat_set_already_added(false);
|
||||
original(gui, text);
|
||||
} else {
|
||||
chatEvents.push(ChatEvent{
|
||||
text.substr(gui->minecraft->player->username.size() + 3),
|
||||
chat_is_sending() ? gui->minecraft->player->id : 0
|
||||
});
|
||||
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 {
|
||||
api_add_chat_event(NULL, text);
|
||||
}
|
||||
recursing = true;
|
||||
original(gui, text);
|
||||
recursing = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool enabled = false;
|
||||
void api_add_chat_event(Entity *sender, const std::string &message) {
|
||||
if (!enabled) return;
|
||||
chatEvents.push(ChatEvent{message, sender ? sender->id : 0});
|
||||
}
|
||||
|
||||
void init_api() {
|
||||
if (feature_has("Implement RaspberryJuice API", server_enabled)) {
|
||||
enabled = true;
|
||||
overwrite_calls(CommandServer_parse, CommandServer_parse_injection);
|
||||
overwrite_calls(Arrow_tick, Arrow_tick_injection);
|
||||
overwrite_call((void *) 0x8b1e8, (void *) Arrow_tick_HitResult_constructor_injection);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/misc/misc.h>
|
||||
#include <mods/init/init.h>
|
||||
#include <mods/feature/feature.h>
|
||||
#include "chat-internal.h"
|
||||
@ -34,7 +35,22 @@ static void send_api_chat_command(const Minecraft *minecraft, const char *str) {
|
||||
std::string _chat_get_prefix(const char *username) {
|
||||
return std::string("<") + username + "> ";
|
||||
}
|
||||
void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, const char *username, const char *message) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
api_add_chat_event(sender, message);
|
||||
username = ((Player *) sender)->username.c_str();
|
||||
} else {
|
||||
username = Strings::default_username;
|
||||
}
|
||||
std::string full_message = _chat_get_prefix(username) + message;
|
||||
char *raw_str = strdup(full_message.c_str());
|
||||
ALLOC_CHECK(raw_str);
|
||||
@ -50,7 +66,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, Strings::default_username, (char *) message);
|
||||
chat_send_message(server_side_network_handler, NULL, (char *) message);
|
||||
} else {
|
||||
// Client
|
||||
rak_net_instance->send(*(Packet *) packet);
|
||||
@ -69,9 +85,8 @@ static void CommandServer_parse_CommandServer_dispatchPacket_injection(const Com
|
||||
static void ServerSideNetworkHandler_handle_ChatPacket_injection(ServerSideNetworkHandler *server_side_network_handler, const RakNet_RakNetGUID &rak_net_guid, ChatPacket *chat_packet) {
|
||||
const Player *player = server_side_network_handler->getPlayer(rak_net_guid);
|
||||
if (player != nullptr) {
|
||||
const char *username = player->username.c_str();
|
||||
const char *message = chat_packet->message.c_str();
|
||||
chat_send_message(server_side_network_handler, username, message);
|
||||
chat_send_message(server_side_network_handler, (Entity *) player, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,13 +128,8 @@ static std::vector<std::string> get_debug_info_right(const Minecraft *minecraft)
|
||||
z = entity->z;
|
||||
type = "Entity";
|
||||
type_info.push_back("ID: " + std::to_string(entity->id));
|
||||
std::string type_str = "Type: ";
|
||||
if (entity->isPlayer()) {
|
||||
type_str += "Player";
|
||||
} else {
|
||||
type_str += misc_get_entity_names()[entity->getEntityTypeId()];
|
||||
}
|
||||
type_str += " (" + std::to_string(entity->getEntityTypeId()) + ")";
|
||||
std::string type_str = "Type: " + misc_get_entity_type_name(entity)
|
||||
+ " (" + std::to_string(entity->getEntityTypeId()) + ")";
|
||||
type_info.push_back(type_str);
|
||||
if (entity->isMob()) {
|
||||
Mob *mob = (Mob *) entity;
|
||||
|
@ -135,8 +135,7 @@ void misc_render_background(int color, const Minecraft *minecraft, const int x,
|
||||
}
|
||||
|
||||
// Get Player's Username
|
||||
std::string misc_get_player_username(Player *player, bool convert_to_utf) {
|
||||
if (!convert_to_utf) return player->username;
|
||||
std::string misc_get_player_username(Player *player) {
|
||||
const std::string *username = &player->username;
|
||||
char *safe_username_c = from_cp437(username->c_str());
|
||||
std::string safe_username = safe_username_c;
|
||||
@ -146,8 +145,6 @@ std::string misc_get_player_username(Player *player, bool convert_to_utf) {
|
||||
|
||||
std::map<int, std::string> &misc_get_entity_names() {
|
||||
static std::map<int, std::string> entity_names = {
|
||||
// Unsavables
|
||||
{0, "Unknown"},
|
||||
// Animals
|
||||
{10, "Chicken"}, {11, "Cow"}, {12, "Pig"}, {13, "Sheep"},
|
||||
// Hostiles
|
||||
@ -161,27 +158,36 @@ std::map<int, std::string> &misc_get_entity_names() {
|
||||
};
|
||||
|
||||
|
||||
std::string misc_get_entity_name(Entity *entity) {
|
||||
if (entity == NULL) {
|
||||
return "";
|
||||
} else if (entity->isPlayer()) {
|
||||
return misc_get_player_username((Player *) entity);
|
||||
} else {
|
||||
int type = entity->getEntityTypeId();
|
||||
std::map<int, std::string> &names = misc_get_entity_names();
|
||||
if (names.find(type) != names.end()) return names[type];
|
||||
return "";
|
||||
}
|
||||
std::string misc_get_entity_name(Entity *entity, bool convert_to_utf) {
|
||||
if (!entity) return "";
|
||||
if (entity->isPlayer()) return convert_to_utf ? misc_get_player_username((Player *) entity) : ((Player *) entity)->username;
|
||||
return misc_get_entity_type_name(entity);
|
||||
}
|
||||
|
||||
std::string misc_get_entity_name_upper(Entity *entity) {
|
||||
std::string ret = misc_get_entity_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);
|
||||
if (entity != NULL && !entity->isPlayer()) {
|
||||
for (char &c : ret) c = toupper(c);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string misc_get_entity_type_name(Entity *entity) {
|
||||
if (!entity) {
|
||||
return "";
|
||||
} else if (entity->isPlayer()) {
|
||||
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";
|
||||
std::map<int, std::string> &names = misc_get_entity_names();
|
||||
if (names.find(type) != names.end()) return names[type];
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
Entity *misc_make_entity_from_id(Level *level, int id) {
|
||||
if (id < 0x40) {
|
||||
return (Entity *) MobFactory::CreateMob(id, level);
|
||||
|
@ -129,7 +129,7 @@ static void find_players(Minecraft *minecraft, const std::string &target_usernam
|
||||
for (std::size_t i = 0; i < players.size(); i++) {
|
||||
// Iterate Players
|
||||
Player *player = players[i];
|
||||
std::string username = misc_get_player_username(player, true);
|
||||
std::string username = misc_get_player_username(player);
|
||||
if (all_players || username == target_username) {
|
||||
// Run Callback
|
||||
callback(minecraft, username, player);
|
||||
|
@ -70,6 +70,7 @@ set(SRC
|
||||
src/entity/Arrow.def
|
||||
src/entity/ArrowRenderer.def
|
||||
src/entity/PaintingRenderer.def
|
||||
src/entity/Particle.def
|
||||
src/entity/Throwable.def
|
||||
src/level/container/FillingContainer.def
|
||||
src/level/container/Container.def
|
||||
|
3
symbols/src/entity/Particle.def
Normal file
3
symbols/src/entity/Particle.def
Normal file
@ -0,0 +1,3 @@
|
||||
extends Entity;
|
||||
|
||||
vtable 0x105b68;
|
Loading…
Reference in New Issue
Block a user