Per-player and per-entity events
So much for "MCPI limitations"!
This commit is contained in:
parent
2ea637581d
commit
245cc4dea5
@ -30,6 +30,7 @@ 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);
|
||||||
|
std::string misc_get_entity_name_upper(Entity *entity);
|
||||||
Entity *misc_make_entity_from_id(Level *level, int id);
|
Entity *misc_make_entity_from_id(Level *level, int id);
|
||||||
|
|
||||||
std::string misc_base64_encode(const std::string &data);
|
std::string misc_base64_encode(const std::string &data);
|
||||||
|
@ -19,14 +19,14 @@ This includes:
|
|||||||
- Gets a list of chat messages, see the limitations section down below to see why it has a zero
|
- Gets a list of chat messages, see the limitations section down below to see why it has a zero
|
||||||
- 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
|
|
||||||
- [x] `player.events.chat.posts() -> {"0", message}[]`
|
- [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
|
- 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}` (and `player.events.projectile.hits()` and `entity.events.projectile.hits(id: 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
|
||||||
- When target id is 0, it means the projectile hit a block and (x, y, z) is the block's position
|
- When target id is 0, it means the projectile hit a block and (x, y, z) is the block's position
|
||||||
- When compatibility mode is disabled, the constant "1" is removed in the return value, leaving just the useful information
|
- When compatibility mode is disabled, the constant "1" is removed in the return value, leaving just the useful information
|
||||||
|
- When compatibility mode is disabled, the owner's name is the owner's id instead, as players can have duplicate names
|
||||||
- Unlike RaspberryJuice, the last argument is the hit entity id, not the entity's name. This shouldn't break anything, and indeed should be more useful.
|
- Unlike RaspberryJuice, the last argument is the hit entity id, not the entity's name. This shouldn't break anything, and indeed should be more useful.
|
||||||
- [x] `player.setDirection(x: float, y: float, z: float)`
|
- [x] `player.setDirection(x: float, y: float, z: float)`
|
||||||
- sets rotation as if the player was at 0, 0, 0 and looking towards (x, y, z)
|
- sets rotation as if the player was at 0, 0, 0 and looking towards (x, y, z)
|
||||||
@ -83,12 +83,16 @@ This includes:
|
|||||||
- Gets the absolute position of the player, aka, without passing it through `OffsetPosTranslator`
|
- Gets the absolute position of the player, aka, without passing it through `OffsetPosTranslator`
|
||||||
- [x] `player.setAbsPos(x: int, y: int, z: int)`
|
- [x] `player.setAbsPos(x: int, y: int, z: int)`
|
||||||
- Sets the absolute position of the player, aka, without passing it through `OffsetPosTranslator`
|
- Sets the absolute position of the player, aka, without passing it through `OffsetPosTranslator`
|
||||||
|
- [x] `player.events.block.hits()` and `entity.events.block.hits(id: int)`, both return `{x: int, y: int, z: int, face: int, hitter: int}`
|
||||||
|
- Same as `events.block.hits`, but for only the player or entity with the id. Only block hits in creative with an iron sword are counted
|
||||||
|
- [x] `player.events.clear()` and `entity.events.clear(id: int)`
|
||||||
|
- These clear projectile, block hit, and chat events for the player or entity
|
||||||
|
- [x] `events.clear` has been changed
|
||||||
|
- It will clear block hit events and chat events, and when compat mode is disabled; projectile events
|
||||||
|
|
||||||
|
Due to MCPI limitations:
|
||||||
It does not implement (due to MCPI limitations):
|
- `events.chat.posts`'s id field is set to 0 for messages that did not come from the main player
|
||||||
- Per-entity events
|
- `events.block.hits` (and more specialized calls), only work in creative or creator mode
|
||||||
- Per-player events besides `player.events.chat.posts` for the main player
|
|
||||||
- `events.chat.posts`'s id field is always set to 0
|
|
||||||
|
|
||||||
Egdecases:
|
Egdecases:
|
||||||
- `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.
|
||||||
@ -99,6 +103,7 @@ Egdecases:
|
|||||||
|
|
||||||
Extras:
|
Extras:
|
||||||
- Compatibility mode, this is enabled by default, and can be changed with `reborn.disableCompatMode` or `reborn.enableCompatMode`.
|
- Compatibility mode, this is enabled by default, and can be changed with `reborn.disableCompatMode` or `reborn.enableCompatMode`.
|
||||||
|
- `events.clear`
|
||||||
|
|
||||||
## How does it work?
|
## How does it work?
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ static std::string getEntityData(CommandServer *commandserver, Entity *entity) {
|
|||||||
// type
|
// type
|
||||||
std::to_string(entity->getEntityTypeId()) + "," +
|
std::to_string(entity->getEntityTypeId()) + "," +
|
||||||
// name
|
// name
|
||||||
misc_get_entity_name(entity) + "," +
|
misc_get_entity_name_upper(entity) + "," +
|
||||||
// x
|
// x
|
||||||
std::to_string(x) + "," +
|
std::to_string(x) + "," +
|
||||||
// y
|
// y
|
||||||
@ -87,7 +87,9 @@ static float distance_between(Entity *e1, Entity *e2) {
|
|||||||
struct ProjectileHitEvent {
|
struct ProjectileHitEvent {
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
std::string owner = "";
|
std::string owner = "";
|
||||||
|
int owner_id = 0;
|
||||||
int targetId = 0;
|
int targetId = 0;
|
||||||
|
bool invalid = false;
|
||||||
|
|
||||||
std::string toString(CommandServer *commandserver) {
|
std::string toString(CommandServer *commandserver) {
|
||||||
float nx = x, ny = y, nz = z;
|
float nx = x, ny = y, nz = z;
|
||||||
@ -96,13 +98,14 @@ struct ProjectileHitEvent {
|
|||||||
+ std::to_string((int) ny) + ","
|
+ std::to_string((int) ny) + ","
|
||||||
+ std::to_string((int) nz) + ","
|
+ std::to_string((int) nz) + ","
|
||||||
+ (compat_mode ? "1," : "")
|
+ (compat_mode ? "1," : "")
|
||||||
+ owner + "," + std::to_string(targetId);
|
+ (compat_mode ? owner : std::to_string(owner_id)) + "," + std::to_string(targetId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChatEvent {
|
struct ChatEvent {
|
||||||
std::string message = "";
|
std::string message = "";
|
||||||
bool from_player = false;
|
int from_player = 0;
|
||||||
|
bool invalid = false;
|
||||||
|
|
||||||
std::string toString() {
|
std::string toString() {
|
||||||
return message;
|
return message;
|
||||||
@ -118,12 +121,8 @@ struct CircularQueue {
|
|||||||
|
|
||||||
void push(T event) {
|
void push(T event) {
|
||||||
buf[at] = event;
|
buf[at] = event;
|
||||||
at++;
|
advance_counter(at);
|
||||||
at %= SIZE;
|
if (at == start) advance_counter(start);
|
||||||
if (at == start) {
|
|
||||||
start++;
|
|
||||||
start %= SIZE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T pop() {
|
T pop() {
|
||||||
@ -131,14 +130,104 @@ struct CircularQueue {
|
|||||||
ERR("Over popped projectile hit events!");
|
ERR("Over popped projectile hit events!");
|
||||||
}
|
}
|
||||||
T ret = buf[start];
|
T ret = buf[start];
|
||||||
start++;
|
advance_counter(start);
|
||||||
start %= EVENT_SIZE;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void advance_counter(int &i) {
|
||||||
|
i += 1;
|
||||||
|
i %= EVENT_SIZE;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
CircularQueue<ProjectileHitEvent> hitEvents{};
|
CircularQueue<ProjectileHitEvent> hitEvents{};
|
||||||
CircularQueue<ChatEvent> chatEvents{};
|
CircularQueue<ChatEvent> chatEvents{};
|
||||||
|
|
||||||
|
void clearEvents(CommandServer *commandserver, int id) {
|
||||||
|
// Clear block hit events
|
||||||
|
if (commandserver->minecraft->isCreativeMode()) {
|
||||||
|
EventList_TileEvent &tileEvents = commandserver->minecraft->getCreator()->getTileEvents();
|
||||||
|
for (int i = tileEvents.at + 1, j = 0; j < tileEvents.len; i++, j++) {
|
||||||
|
if (i == tileEvents.len) i = 0;
|
||||||
|
if (tileEvents.events[i].item.entityId == id)
|
||||||
|
// This will make the API ignore it
|
||||||
|
tileEvents.events[i].tick = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Clear chat events
|
||||||
|
int i = chatEvents.start;
|
||||||
|
while (chatEvents.at != i) {
|
||||||
|
if (chatEvents.buf[i].from_player == id) {
|
||||||
|
chatEvents.buf[i].invalid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Clear projectile events
|
||||||
|
i = hitEvents.start;
|
||||||
|
while (hitEvents.at != i) {
|
||||||
|
if (hitEvents.buf[i].owner_id == id) {
|
||||||
|
hitEvents.buf[i].invalid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getBlockHits(CommandServer *commandserver, ConnectedClient &client, int id) {
|
||||||
|
std::string ret = "";
|
||||||
|
if (commandserver->minecraft->isCreativeMode()) {
|
||||||
|
EventList_TileEvent &tileEvents = commandserver->minecraft->getCreator()->getTileEvents();
|
||||||
|
for (int i = tileEvents.at + 1, j = 0; j < tileEvents.len; i++, j++) {
|
||||||
|
if (i == tileEvents.len) i = 0;
|
||||||
|
if (tileEvents.events[i].item.entityId == id && tileEvents.events[i].tick > client.lastBlockHitPoll) {
|
||||||
|
tileEvents.events[i].tick = -1;
|
||||||
|
float x = tileEvents.events[i].item.x;
|
||||||
|
float y = tileEvents.events[i].item.y;
|
||||||
|
float z = tileEvents.events[i].item.z;
|
||||||
|
commandserver->pos_translator.to(x, y, z);
|
||||||
|
ret +=
|
||||||
|
std::to_string((int) x) + "," +
|
||||||
|
std::to_string((int) y) + "," +
|
||||||
|
std::to_string((int) z) + "," +
|
||||||
|
std::to_string(tileEvents.events[i].item.face) + "," +
|
||||||
|
std::to_string(tileEvents.events[i].item.entityId) + "|";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret.size() > 1) ret.pop_back();
|
||||||
|
return ret + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getChatPosts(int id) {
|
||||||
|
std::string ret = "";
|
||||||
|
int i = chatEvents.start;
|
||||||
|
while (chatEvents.at != i) {
|
||||||
|
ChatEvent ce = chatEvents.buf[i];
|
||||||
|
if (ce.from_player == id && !ce.invalid) {
|
||||||
|
chatEvents.buf[i].invalid = true;
|
||||||
|
std::string message = ce.toString();
|
||||||
|
if (compat_mode) std::replace(message.begin(), message.end(), '|', '\\');
|
||||||
|
else message = misc_base64_encode(message);
|
||||||
|
ret += std::to_string(ce.from_player) + "," + message + "|";
|
||||||
|
}
|
||||||
|
chatEvents.advance_counter(i);
|
||||||
|
}
|
||||||
|
if (ret.size() > 1) ret.pop_back();
|
||||||
|
return ret + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getProjectileHits(CommandServer *commandserver, int id) {
|
||||||
|
std::string ret = "";
|
||||||
|
int i = hitEvents.start;
|
||||||
|
while (hitEvents.at != i) {
|
||||||
|
ProjectileHitEvent he = hitEvents.buf[i];
|
||||||
|
if (he.owner_id == id && !he.invalid) {
|
||||||
|
hitEvents.buf[i].invalid = true;
|
||||||
|
std::string message = he.toString(commandserver);
|
||||||
|
ret += message + "|";
|
||||||
|
}
|
||||||
|
hitEvents.advance_counter(i);
|
||||||
|
}
|
||||||
|
if (ret.size() > 1) ret.pop_back();
|
||||||
|
return ret + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
static const std::string fail = "Fail\n";
|
static const std::string fail = "Fail\n";
|
||||||
std::unordered_map<int, int> modern_entity_id_mapping = {
|
std::unordered_map<int, int> modern_entity_id_mapping = {
|
||||||
{93, 10}, /* Chicken */
|
{93, 10}, /* Chicken */
|
||||||
@ -192,7 +281,7 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
|
|||||||
if (entity == NULL) {
|
if (entity == NULL) {
|
||||||
WARN("Player (or Entity) [%i] not found in entity.getName.", id);
|
WARN("Player (or Entity) [%i] not found in entity.getName.", id);
|
||||||
}
|
}
|
||||||
return misc_get_entity_name(entity) + "\n";
|
return misc_get_entity_name_upper(entity) + "\n";
|
||||||
} else if (cmd == "world.getEntities") {
|
} else if (cmd == "world.getEntities") {
|
||||||
int type;
|
int type;
|
||||||
int ret = sscanf(args.c_str(), "%d", &type);
|
int ret = sscanf(args.c_str(), "%d", &type);
|
||||||
@ -236,33 +325,45 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
|
|||||||
std::string ret = "";
|
std::string ret = "";
|
||||||
while (chatEvents.at != chatEvents.start) {
|
while (chatEvents.at != chatEvents.start) {
|
||||||
ChatEvent ce = chatEvents.pop();
|
ChatEvent ce = chatEvents.pop();
|
||||||
|
if (!ce.invalid) {
|
||||||
std::string message = ce.toString();
|
std::string message = ce.toString();
|
||||||
if (compat_mode) std::replace(message.begin(), message.end(), '|', '\\');
|
if (compat_mode) std::replace(message.begin(), message.end(), '|', '\\');
|
||||||
else message = misc_base64_encode(message);
|
else message = misc_base64_encode(message);
|
||||||
ret += (compat_mode ? "0," : "") + message + "|";
|
ret += std::to_string(ce.from_player) + "," + message + "|";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ret.size() > 1) ret.pop_back();
|
if (ret.size() > 1) ret.pop_back();
|
||||||
return ret + "\n";
|
return ret + "\n";
|
||||||
} else if (cmd == "player.events.chat.posts") {
|
} else if (cmd == "player.events.chat.posts") {
|
||||||
std::string ret = "";
|
return getChatPosts(commandserver->minecraft->player->id);
|
||||||
while (chatEvents.at != chatEvents.start) {
|
} else if (cmd == "entity.events.chat.posts") {
|
||||||
ChatEvent ce = chatEvents.pop();
|
int id;
|
||||||
if (ce.from_player) {
|
int ret = sscanf(args.c_str(), "%d", &id);
|
||||||
std::string message = ce.toString();
|
if (ret != 1) return fail;
|
||||||
if (compat_mode) std::replace(message.begin(), message.end(), '|', '\\');
|
return getChatPosts(id);
|
||||||
else message = misc_base64_encode(message);
|
} else if (cmd == "player.events.block.hits") {
|
||||||
ret += (compat_mode ? "0," : "") + message + "|";
|
return getBlockHits(commandserver, client, commandserver->minecraft->player->id);
|
||||||
}
|
} else if (cmd == "entity.events.block.hits") {
|
||||||
}
|
int id;
|
||||||
if (ret.size() > 1) ret.pop_back();
|
int ret = sscanf(args.c_str(), "%d", &id);
|
||||||
return ret + "\n";
|
if (ret != 1) return fail;
|
||||||
|
return getBlockHits(commandserver, client, id);
|
||||||
} else if (cmd == "events.projectile.hits") {
|
} else if (cmd == "events.projectile.hits") {
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
while (hitEvents.at != hitEvents.start) {
|
while (hitEvents.at != hitEvents.start) {
|
||||||
result += hitEvents.pop().toString(commandserver) + "|";
|
ProjectileHitEvent he = hitEvents.pop();
|
||||||
|
if (!he.invalid)
|
||||||
|
result += he.toString(commandserver) + "|";
|
||||||
}
|
}
|
||||||
if (result.size() > 1) result.pop_back();
|
if (result.size() > 1) result.pop_back();
|
||||||
return result + "\n";
|
return result + "\n";
|
||||||
|
} else if (cmd == "player.events.projectile.hits") {
|
||||||
|
return getProjectileHits(commandserver, commandserver->minecraft->player->id);
|
||||||
|
} else if (cmd == "entity.events.projectile.hits") {
|
||||||
|
int id;
|
||||||
|
int ret = sscanf(args.c_str(), "%d", &id);
|
||||||
|
if (ret != 1) return fail;
|
||||||
|
return getProjectileHits(commandserver, id);
|
||||||
} else if (cmd == "player.setDirection" && commandserver->minecraft->player) {
|
} else if (cmd == "player.setDirection" && commandserver->minecraft->player) {
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
int ret = sscanf(args.c_str(), "%f,%f,%f", &x, &y, &z);
|
int ret = sscanf(args.c_str(), "%f,%f,%f", &x, &y, &z);
|
||||||
@ -452,6 +553,7 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
|
|||||||
result += "," + i.second + "|";
|
result += "," + i.second + "|";
|
||||||
}
|
}
|
||||||
if (result.size() > 1) result.pop_back();
|
if (result.size() > 1) result.pop_back();
|
||||||
|
for (auto &c : result) c = toupper(c);
|
||||||
return result + "\n";
|
return result + "\n";
|
||||||
} else if (cmd == "player.setAbsPos" && commandserver->minecraft->player) {
|
} else if (cmd == "player.setAbsPos" && commandserver->minecraft->player) {
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
@ -462,6 +564,20 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
|
|||||||
return std::to_string(commandserver->minecraft->player->x) + ","
|
return std::to_string(commandserver->minecraft->player->x) + ","
|
||||||
+ std::to_string(commandserver->minecraft->player->y) + ","
|
+ std::to_string(commandserver->minecraft->player->y) + ","
|
||||||
+ std::to_string(commandserver->minecraft->player->z) + "\n";
|
+ std::to_string(commandserver->minecraft->player->z) + "\n";
|
||||||
|
} else if (cmd == "player.events.clear") {
|
||||||
|
clearEvents(commandserver, commandserver->minecraft->player->id);
|
||||||
|
} else if (cmd == "entity.events.clear") {
|
||||||
|
int id;
|
||||||
|
int ret = sscanf(args.c_str(), "%d", &id);
|
||||||
|
if (ret != 1) return fail;
|
||||||
|
clearEvents(commandserver, id);
|
||||||
|
} else if (cmd == "events.clear") {
|
||||||
|
// Clear chat events
|
||||||
|
chatEvents.at = chatEvents.start;
|
||||||
|
// Clear projectile events
|
||||||
|
if (!compat_mode) hitEvents.at = hitEvents.start;
|
||||||
|
// Extended the original, so now call the original
|
||||||
|
return old(commandserver, client, command);
|
||||||
} else if (cmd == "reborn.disableCompatMode") {
|
} else if (cmd == "reborn.disableCompatMode") {
|
||||||
compat_mode = false;
|
compat_mode = false;
|
||||||
} else if (cmd == "reborn.enableCompatMode") {
|
} else if (cmd == "reborn.enableCompatMode") {
|
||||||
@ -486,6 +602,7 @@ static HitResult *Arrow_tick_HitResult_constructor_injection(HitResult *self, En
|
|||||||
.y = (int) target->y,
|
.y = (int) target->y,
|
||||||
.z = (int) target->z,
|
.z = (int) target->z,
|
||||||
.owner = misc_get_player_username((Player *) shooter),
|
.owner = misc_get_player_username((Player *) shooter),
|
||||||
|
.owner_id = shooter->id,
|
||||||
.targetId = target->id
|
.targetId = target->id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -505,6 +622,7 @@ static void Arrow_tick_injection(Arrow_tick_t old, Arrow *self) {
|
|||||||
.y = self->hit_y,
|
.y = self->hit_y,
|
||||||
.z = self->hit_z,
|
.z = self->hit_z,
|
||||||
.owner = misc_get_player_username((Player *) shooter),
|
.owner = misc_get_player_username((Player *) shooter),
|
||||||
|
.owner_id = shooter->id,
|
||||||
.targetId = 0
|
.targetId = 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -524,6 +642,7 @@ static void Throwable_tick_Throwable_onHit_injection(Throwable *self, HitResult
|
|||||||
.y = (int) res->exact.y,
|
.y = (int) res->exact.y,
|
||||||
.z = (int) res->exact.z,
|
.z = (int) res->exact.z,
|
||||||
.owner = misc_get_player_username((Player *) thrower),
|
.owner = misc_get_player_username((Player *) thrower),
|
||||||
|
.owner_id = thrower->id,
|
||||||
.targetId = res->entity->id
|
.targetId = res->entity->id
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@ -533,6 +652,7 @@ static void Throwable_tick_Throwable_onHit_injection(Throwable *self, HitResult
|
|||||||
.y = res->y,
|
.y = res->y,
|
||||||
.z = res->z,
|
.z = res->z,
|
||||||
.owner = misc_get_player_username((Player *) thrower),
|
.owner = misc_get_player_username((Player *) thrower),
|
||||||
|
.owner_id = thrower->id,
|
||||||
.targetId = 0
|
.targetId = 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -546,8 +666,8 @@ static void Gui_addMessage_injection(Gui_addMessage_t original, Gui *gui, const
|
|||||||
original(gui, text);
|
original(gui, text);
|
||||||
} else {
|
} else {
|
||||||
chatEvents.push(ChatEvent{
|
chatEvents.push(ChatEvent{
|
||||||
text,
|
text.substr(gui->minecraft->player->username.size() + 3),
|
||||||
chat_is_sending()
|
chat_is_sending() ? gui->minecraft->player->id : 0
|
||||||
});
|
});
|
||||||
recursing = true;
|
recursing = true;
|
||||||
original(gui, text);
|
original(gui, text);
|
||||||
|
@ -15,7 +15,7 @@ std::string chat_send_api_command(const Minecraft *minecraft, const std::string
|
|||||||
ConnectedClient client;
|
ConnectedClient client;
|
||||||
client.sock = -1;
|
client.sock = -1;
|
||||||
client.str = "";
|
client.str = "";
|
||||||
client.time = 0;
|
client.lastBlockHitPoll = 0;
|
||||||
CommandServer *command_server = minecraft->command_server;
|
CommandServer *command_server = minecraft->command_server;
|
||||||
if (command_server != nullptr) {
|
if (command_server != nullptr) {
|
||||||
return command_server->parse(client, str);
|
return command_server->parse(client, str);
|
||||||
|
@ -38,7 +38,7 @@ static void Minecraft_setIsCreativeMode_injection(Minecraft_setIsCreativeMode_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disable CreatorMode-Specific API Features (Polling Block Hits) In SurvivalMode, This Is Preferable To Crashing
|
// Disable CreatorMode-Specific API Features (Polling Block Hits) In SurvivalMode, This Is Preferable To Crashing
|
||||||
static unsigned char *Minecraft_getCreator_injection(Minecraft_getCreator_t original, Minecraft *minecraft) {
|
static ICreator *Minecraft_getCreator_injection(Minecraft_getCreator_t original, Minecraft *minecraft) {
|
||||||
if (is_survival) {
|
if (is_survival) {
|
||||||
// SurvivalMode, Return nullptr
|
// SurvivalMode, Return nullptr
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -173,6 +173,14 @@ std::string misc_get_entity_name(Entity *entity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string misc_get_entity_name_upper(Entity *entity) {
|
||||||
|
std::string ret = misc_get_entity_name(entity);
|
||||||
|
if (entity != NULL && !entity->isPlayer()) {
|
||||||
|
for (auto &c : ret) c = toupper(c);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
Entity *misc_make_entity_from_id(Level *level, int id) {
|
Entity *misc_make_entity_from_id(Level *level, int id) {
|
||||||
if (id < 0x40) {
|
if (id < 0x40) {
|
||||||
return (Entity *) MobFactory::CreateMob(id, level);
|
return (Entity *) MobFactory::CreateMob(id, level);
|
||||||
|
@ -8,6 +8,11 @@ set(SRC
|
|||||||
src/game/Minecraft.def
|
src/game/Minecraft.def
|
||||||
src/game/mode/GameMode.def
|
src/game/mode/GameMode.def
|
||||||
src/game/mode/CreatorMode.def
|
src/game/mode/CreatorMode.def
|
||||||
|
src/game/mode/ICreator.def
|
||||||
|
src/game/mode/Creator.def
|
||||||
|
src/game/mode/EventList_Item.def
|
||||||
|
src/game/mode/EventList_TileEvent.def
|
||||||
|
src/game/mode/TileEvent.def
|
||||||
src/game/mode/SurvivalMode.def
|
src/game/mode/SurvivalMode.def
|
||||||
src/game/NinecraftApp.def
|
src/game/NinecraftApp.def
|
||||||
src/game/GameRenderer.def
|
src/game/GameRenderer.def
|
||||||
|
@ -2,6 +2,6 @@ size 0xc;
|
|||||||
|
|
||||||
property uint sock = 0x0;
|
property uint sock = 0x0;
|
||||||
property std::string str = 0x4;
|
property std::string str = 0x4;
|
||||||
property int time = 0x8;
|
property int lastBlockHitPoll = 0x8;
|
||||||
|
|
||||||
mark-as-simple;
|
mark-as-simple;
|
@ -12,7 +12,7 @@ method bool isCreativeMode() = 0x17270;
|
|||||||
method void releaseMouse() = 0x15d30;
|
method void releaseMouse() = 0x15d30;
|
||||||
method void grabMouse() = 0x15d10;
|
method void grabMouse() = 0x15d10;
|
||||||
method void leaveGame(bool save_remote_level) = 0x15ea0;
|
method void leaveGame(bool save_remote_level) = 0x15ea0;
|
||||||
method uchar *getCreator() = 0x17538;
|
method ICreator *getCreator() = 0x17538;
|
||||||
method LevelStorageSource *getLevelSource() = 0x16e84;
|
method LevelStorageSource *getLevelSource() = 0x16e84;
|
||||||
method void handleMouseDown(int param_1, bool can_destroy) = 0x1584c;
|
method void handleMouseDown(int param_1, bool can_destroy) = 0x1584c;
|
||||||
method void handleBuildAction(uint *build_action_intention) = 0x15920;
|
method void handleBuildAction(uint *build_action_intention) = 0x15920;
|
||||||
|
7
symbols/src/game/mode/Creator.def
Normal file
7
symbols/src/game/mode/Creator.def
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
size 0x20;
|
||||||
|
|
||||||
|
extends ICreator;
|
||||||
|
vtable 0x1a0dc;
|
||||||
|
|
||||||
|
property EventList_TileEvent tileEvents = 0x4;
|
||||||
|
property int tick = 0x1c;
|
@ -1,5 +1,8 @@
|
|||||||
extends GameMode;
|
extends GameMode;
|
||||||
|
|
||||||
size 0x1c;
|
size 0x1c;
|
||||||
|
vtable 0x102d00;
|
||||||
|
|
||||||
constructor (Minecraft *minecraft) = 0x1a044;
|
constructor (Minecraft *minecraft) = 0x1a044;
|
||||||
|
|
||||||
|
property Creator *creator = 0x4;
|
||||||
|
6
symbols/src/game/mode/EventList_Item.def
Normal file
6
symbols/src/game/mode/EventList_Item.def
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
size 0x18;
|
||||||
|
|
||||||
|
property int tick = 0x0;
|
||||||
|
property TileEvent item = 0x4;
|
||||||
|
|
||||||
|
mark-as-simple;
|
8
symbols/src/game/mode/EventList_TileEvent.def
Normal file
8
symbols/src/game/mode/EventList_TileEvent.def
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
size 0x18;
|
||||||
|
|
||||||
|
property int at = 0x0;
|
||||||
|
property int len = 0x4;
|
||||||
|
property int cap = 0x8;
|
||||||
|
property std::vector<EventList_Item> events = 0xc;
|
||||||
|
|
||||||
|
mark-as-simple;
|
3
symbols/src/game/mode/ICreator.def
Normal file
3
symbols/src/game/mode/ICreator.def
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
vtable 0x102ca8;
|
||||||
|
|
||||||
|
virtual-method EventList_TileEvent &getTileEvents() = 0x8;
|
9
symbols/src/game/mode/TileEvent.def
Normal file
9
symbols/src/game/mode/TileEvent.def
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
size 0x14;
|
||||||
|
|
||||||
|
property int entityId = 0x0;
|
||||||
|
property int x = 0x4;
|
||||||
|
property int y = 0x8;
|
||||||
|
property int z = 0xc;
|
||||||
|
property int face = 0x10;
|
||||||
|
|
||||||
|
mark-as-simple;
|
Loading…
Reference in New Issue
Block a user