Fix Gui_addMessage injection for the API and tidy

This commit is contained in:
Bigjango13 2024-10-27 00:51:12 -07:00
parent 66e082695f
commit 0b6675231e
5 changed files with 30 additions and 24 deletions

View File

@ -30,5 +30,6 @@ void misc_run_on_swap_buffers(const std::function<void()> &function);
std::string misc_get_player_username(Player *player); std::string misc_get_player_username(Player *player);
std::map<int, std::string> &misc_get_entity_names(); std::map<int, std::string> &misc_get_entity_names();
std::string misc_get_entity_name(Entity *entity); std::string misc_get_entity_name(Entity *entity);
Entity *misc_make_entity_from_id(Level *level, int id);
static constexpr int line_height = 8; static constexpr int line_height = 8;

View File

@ -20,7 +20,8 @@ This includes:
- When compatibility mode is enabled, `|` in the chat messages is replaced with `\` - When compatibility mode is enabled, `|` in the chat messages is replaced with `\`
- When compatibility mode is disabled, `|` in the chat messages is replaced with `\|` - When compatibility mode is disabled, `|` in the chat messages is replaced with `\|`
- When compatibility mode is disabled, the first "0" is removed, so the return value is just the message - When compatibility mode is disabled, the first "0" is removed, so the return value is just the message
- The messages are not cleared - [x] `player.events.chat.posts() -> {"0", message}[]`
- This is *exactly* the same as `events.chat.posts`, however it only returns chat messages sent by the player
- [x] `events.projectile.hits() -> {x: int, y: int, z: int, "1", owner: string, target: int}` - [x] `events.projectile.hits() -> {x: int, y: int, z: int, "1", owner: string, target: int}`
- Returns a list of projectile hit events, the list is cleared each time it is read by this call - Returns a list of projectile hit events, the list is cleared each time it is read by this call
- When target id is not 0, it means the projectile hit an entity and (x, y, z) is the entity's position - When target id is not 0, it means the projectile hit an entity and (x, y, z) is the entity's position
@ -86,12 +87,10 @@ This includes:
It does not implement (due to MCPI limitations): It does not implement (due to MCPI limitations):
- Per-entity events - Per-entity events
- Per-player events - Per-player events besides `player.events.chat.posts` for the main player
- `events.chat.posts`'s id field is always set to -1 - `events.chat.posts`'s id field is always set to 0
- `events.chat.posts` only returns the last 30 messages, and does *not* clear them after each API call
Egdecases: Egdecases:
- `world.removeEntity` will remove a player if given a players id.
- `world.removeEntities`/`player.removeEntities`/`entity.removeEntities` will not remove players when given 0 or -1 for type. - `world.removeEntities`/`player.removeEntities`/`entity.removeEntities` will not remove players when given 0 or -1 for type.
- `entity.getName` will not get the name of non-player entities with a type id of 0 due to ambiguity. - `entity.getName` will not get the name of non-player entities with a type id of 0 due to ambiguity.
- All Raspberry Juice commands/responses involving the player name are designed around the MCJE username restrictions, not the much looser MCPI restrictions. They may cause problems. - All Raspberry Juice commands/responses involving the player name are designed around the MCJE username restrictions, not the much looser MCPI restrictions. They may cause problems.

View File

@ -444,14 +444,9 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
x += ix - ix1; x += ix - ix1;
y += iy - iy1; y += iy - iy1;
z += iz - iz1; z += iz - iz1;
if (compat_mode && modern_entity_id_mapping.find(id) != modern_entity_id_mapping.end()) id = modern_entity_id_mapping[id]; if (compat_mode && modern_entity_id_mapping.contains(id)) id = modern_entity_id_mapping[id];
// Spawn // Spawn
Entity *entity = NULL; Entity *entity = misc_make_entity_from_id(commandserver->minecraft->level, id);
if (id < 0x40) {
entity = (Entity *) MobFactory::CreateMob(id, commandserver->minecraft->level);
} else {
entity = EntityFactory::CreateEntity(id, commandserver->minecraft->level);
}
if (entity == NULL) return fail; if (entity == NULL) return fail;
entity->moveTo(x, y, z, 0, 0); entity->moveTo(x, y, z, 0, 0);
commandserver->minecraft->level->addEntity(entity); commandserver->minecraft->level->addEntity(entity);
@ -459,7 +454,7 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
} else if (cmd == "world.getEntityTypes") { } else if (cmd == "world.getEntityTypes") {
std::string result = ""; std::string result = "";
for (auto &i : misc_get_entity_names()) { for (auto &i : misc_get_entity_names()) {
if (compat_mode && modern_entity_id_mapping.find(i.first) != modern_entity_id_mapping.end()) result += std::to_string(modern_entity_id_mapping[i.first]); if (compat_mode && modern_entity_id_mapping.contains(i.first)) result += std::to_string(modern_entity_id_mapping[i.first]);
else result += std::to_string(i.first); else result += std::to_string(i.first);
result += "," + i.second + "|"; result += "," + i.second + "|";
} }
@ -490,12 +485,7 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
static Entity *shooter = NULL; static Entity *shooter = NULL;
static HitResult *Arrow_tick_HitResult_constructor_injection(HitResult *self, Entity *target) { static HitResult *Arrow_tick_HitResult_constructor_injection(HitResult *self, Entity *target) {
// Orignal // Orignal
self->type = 1; self->constructor(target);
self->entity = target;
self->unknown = false;
self->exact.x = target->x;
self->exact.y = target->y;
self->exact.z = target->z;
// Add event // Add event
if (shooter && shooter->isPlayer()) { if (shooter && shooter->isPlayer()) {
push_circular_queue(ProjectileHitEvent{ push_circular_queue(ProjectileHitEvent{
@ -558,11 +548,18 @@ 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 void Gui_addMessage_injection(Gui_addMessage_t original, Gui *gui, const std::string &text) {
push_circular_queue(ChatEvent{ static bool recursing = false;
text, if (recursing) {
is_sending_to_chat() original(gui, text);
}, chatEvents, chat_events_start, chat_events_at); } else {
original(gui, text); push_circular_queue(ChatEvent{
text,
is_sending_to_chat()
}, chatEvents, chat_events_start, chat_events_at);
recursing = true;
original(gui, text);
recursing = false;
}
} }
void init_api() { void init_api() {

View File

@ -173,6 +173,13 @@ std::string misc_get_entity_name(Entity *entity) {
} }
} }
Entity *misc_make_entity_from_id(Level *level, int id) {
if (id < 0x40) {
return (Entity *) MobFactory::CreateMob(id, level);
}
return EntityFactory::CreateEntity(id, level);
}
// Init // Init
void _init_misc_api() { void _init_misc_api() {
// Handle Custom Creative Inventory Setup Behavior // Handle Custom Creative Inventory Setup Behavior

View File

@ -1,5 +1,7 @@
size 0x28; size 0x28;
constructor (Entity *entity) = 0xd3a98;
property int type = 0x0; property int type = 0x0;
property int x = 0x4; property int x = 0x4;
property int y = 0x8; property int y = 0x8;