commit - e5dfe53d14c67dcf18bf7c84a672eb490a0329dc
commit + c5e84080528d6b4a6defd2599770a5c60149de1c
blob - 06f8368e342a02b0d903ea07aeb4a7b94c37d186
blob + c5942b9ea0c23362acaca9e0cc6e065a5d6fdc4b
--- include/globals.h
+++ include/globals.h
#pragma pack(pop)
+union EntityDataValue {
+ uint8_t byte;
+ int pose;
+};
+
+typedef struct {
+ uint8_t index;
+ // 0 - Byte
+ // 21 - Pose
+ int type;
+ union EntityDataValue value;
+} EntityData;
+
extern BlockChange block_changes[MAX_BLOCK_CHANGES];
extern int block_changes_count;
blob - 4d3b36cd73eed7d55c33642fa532ddfe6a6a1d73
blob + ae832ac729d08016f73fc59fb9f192ae60644ce8
--- include/packets.h
+++ include/packets.h
int sc_playerInfoUpdateAddPlayer (int client_fd, PlayerData player);
int sc_spawnEntity (int client_fd, int id, uint8_t *uuid, int type, double x, double y, double z, uint8_t yaw, uint8_t pitch);
int sc_spawnEntityPlayer (int client_fd, PlayerData player);
+int sc_setEntityMetadata (int client_fd, int id, EntityData *metadata, size_t length);
int sc_entityAnimation (int client_fd, int id, uint8_t animation);
int sc_teleportEntity (int client_fd, int id, double x, double y, double z, float yaw, float pitch);
int sc_setHeadRotation (int client_fd, int id, uint8_t yaw);
blob - 1dde7933359ecaa0ac637e183cf8e78eacf20109
blob + 62d09f06244a60ebd35fe543924216f2eb7fb58d
--- include/procedures.h
+++ include/procedures.h
int givePlayerItem (PlayerData *player, uint16_t item, uint8_t count);
void spawnPlayer (PlayerData *player);
+void broadcastPlayerMetadata (PlayerData *player);
+
uint8_t serverSlotToClientSlot (int window_id, uint8_t slot);
uint8_t clientSlotToServerSlot (int window_id, uint8_t slot);
void broadcastChestUpdate (int origin_fd, uint8_t *storage_ptr, uint16_t item, uint8_t count, uint8_t slot);
+ssize_t writeEntityData (int client_fd, EntityData *data);
+
+int sizeEntityData (EntityData *data);
+int sizeEntityMetadata (EntityData *metadata, size_t length);
+
#endif
blob - 5cc1a51e31e791d131addf9f6a7cbdfcd424504a
blob + 8b67b5f0f1717df494922a2071a74a58629b77e0
--- src/packets.c
+++ src/packets.c
*on_ground = readByte(client_fd) & 0x01;
+ PlayerData *player;
+ if (!getPlayerData(client_fd, &player))
+ broadcastPlayerMetadata(player);
+
return 0;
}
return 0;
}
+// S->C Set Entity Metadata
+int sc_setEntityMetadata (int client_fd, int id, EntityData *metadata, size_t length) {
+ int entity_metadata_size = sizeEntityMetadata(metadata, length);
+ if (entity_metadata_size == -1) return 1;
+
+ writeVarInt(client_fd, 2 + sizeVarInt(id) + entity_metadata_size);
+ writeByte(client_fd, 0x5C);
+
+ writeVarInt(client_fd, id); // Entity ID
+
+ for (size_t i = 0; i < length; i ++) {
+ EntityData *data = &metadata[i];
+ writeEntityData(client_fd, data);
+ }
+
+ writeByte(client_fd, 0xFF); // End
+
+ return 0;
+}
+
// S->C Spawn Entity (from PlayerData)
int sc_spawnEntityPlayer (int client_fd, PlayerData player) {
return sc_spawnEntity(
if (flags & 0x20) player->flags |= 0x04;
else player->flags &= ~0x04;
+ broadcastPlayerMetadata(player);
+
return 0;
}
if (action == 1) player->flags |= 0x08;
else if (action == 2) player->flags &= ~0x08;
+ broadcastPlayerMetadata(player);
+
return 0;
}
blob - 464e7a4df918d7c63b3d2568dbc3d194f7974d27
blob + 7ba75da40d5d01df149e3fe5caa2ec4459485a32
--- src/procedures.c
+++ src/procedures.c
}
+// Broadcasts a player's entity metadata (sneak/sprint state) to other players
+void broadcastPlayerMetadata (PlayerData *player) {
+ uint8_t sneaking = (player->flags & 0x04) != 0;
+ uint8_t sprinting = (player->flags & 0x08) != 0;
+
+ uint8_t player_bit_mask = 0;
+ if (sneaking) player_bit_mask |= 0x02;
+ if (sprinting) player_bit_mask |= 0x08;
+
+ int pose = 0;
+ if (sneaking) pose = 5;
+
+ EntityData metadata[] = {
+ {
+ 0, // Index (Bit Mask)
+ 0, // Type (Byte)
+ player_bit_mask, // Value
+ },
+ {
+ 6, // Index (Pose),
+ 21, // Type (Pose),
+ pose, // Value (Standing)
+ }
+ };
+
+ for (int i = 0; i < MAX_PLAYERS; i ++) {
+ PlayerData* other_player = &player_data[i];
+ int client_fd = other_player->client_fd;
+
+ if (client_fd == -1) continue;
+ if (client_fd == player->client_fd) continue;
+ if (other_player->flags & 0x20) continue;
+
+ sc_setEntityMetadata(client_fd, player->client_fd, metadata, 2);
+ }
+}
+
uint8_t getBlockChange (short x, uint8_t y, short z) {
for (int i = 0; i < block_changes_count; i ++) {
if (block_changes[i].block == 0xFF) continue;
}
#endif
+
+ssize_t writeEntityData (int client_fd, EntityData *data) {
+ writeByte(client_fd, data->index);
+ writeVarInt(client_fd, data->type);
+
+ switch (data->type) {
+ case 0: // Byte
+ return writeByte(client_fd, data->value.byte);
+ case 21: // Pose
+ writeVarInt(client_fd, data->value.pose);
+ return 0;
+
+ default: return -1;
+ }
+}
+
+// Returns the networked size of an EntityData entry
+int sizeEntityData (EntityData *data) {
+ int value_size;
+
+ switch (data->type) {
+ case 0: // Byte
+ value_size = 1;
+ break;
+ case 21: // Pose
+ value_size = sizeVarInt(data->value.pose);
+ break;
+
+ default: return -1;
+ }
+
+ return 1 + sizeVarInt(data->type) + value_size;
+}
+
+// Returns the networked size of an array of EntityData entries
+int sizeEntityMetadata (EntityData *metadata, size_t length) {
+ int total_size = 0;
+ for (size_t i = 0; i < length; i ++) {
+ int size = sizeEntityData(&metadata[i]);
+ if (size == -1) return -1;
+ total_size += size;
+ }
+ return total_size;
+}
blob - fabb6f097be7f7314556a178a854c0acc6b2df05
blob + 0b7050f9785d2d07f62890ca08ae09b4c24b3ecc
--- src/tools.c
+++ src/tools.c
if (err == WSAEWOULDBLOCK || err == WSAEINTR) {
#else
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
- #endif
+ #endif
// handle network timeout
if (get_program_time() - last_update_time > NETWORK_TIMEOUT_TIME) {
disconnectClient(&client_fd, -2);