From 478173d6165455ada35d54be0b618f0eb4d9dfdb Mon Sep 17 00:00:00 2001 From: p2r3 Date: Tue, 12 Aug 2025 12:48:28 +0300 Subject: [PATCH] refactor to use struct instead of byte buffer --- main.c | 39 +++++----- src/globals.c | 15 +--- src/globals.h | 39 ++++++---- src/packets.c | 65 ++++++----------- src/tools.c | 195 +++++++++++++++++++++----------------------------- src/tools.h | 6 +- 6 files changed, 154 insertions(+), 205 deletions(-) diff --git a/main.c b/main.c index 47e6b39..1d2095b 100644 --- a/main.c +++ b/main.c @@ -56,21 +56,17 @@ void handlePacket (int client_fd, int length, int packet_id) { sc_loginPlay(client_fd); - short x = 8, y = 80, z = 8; - int8_t yaw = 0, pitch = 0; - restorePlayerPosition(client_fd, &x, &y, &z, &yaw, &pitch); - sc_synchronizePlayerPosition(client_fd, x, y, z, yaw * 180 / 127, pitch * 90 / 127); + PlayerData *player; + if (getPlayerData(client_fd, &player)) break; - short _x = x / 16, _z = z / 16; + sc_synchronizePlayerPosition(client_fd, player->x, player->y, player->z, player->yaw * 180 / 127, player->pitch * 90 / 127); - uint8_t *inventory = getPlayerInventory(client_fd); - uint16_t item; - for (uint8_t i = 0; i < 123; i += 3) { - memcpy(&item, inventory + i, 2); - sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(i / 3), inventory[i + 2], item); + for (uint8_t i = 0; i < 41; i ++) { + sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(i), player->inventory_count[i], player->inventory_items[i]); } - sc_setHeldItem(client_fd, *(inventory - 1)); + sc_setHeldItem(client_fd, player->hotbar); + short _x = player->x / 16, _z = player->z / 16; sc_setDefaultSpawnPosition(client_fd, 8, 80, 8); sc_startWaitingForChunks(client_fd); sc_setCenterChunk(client_fd, _x, _z); @@ -116,13 +112,13 @@ void handlePacket (int client_fd, int length, int packet_id) { if (packet_id == 0x1D) cs_setPlayerPosition(client_fd, &x, &y, &z); else cs_setPlayerPositionAndRotation(client_fd, &x, &y, &z, &yaw, &pitch); - short cx = x + 0.5, cy = y, cz = z + 0.5; - short px, py, pz; - restorePlayerPosition (client_fd, &px, &py, &pz, NULL, NULL); + + PlayerData *player; + if (getPlayerData(client_fd, &player)) break; short _x = (cx < 0 ? cx - 16 : cx) / 16, _z = (cz < 0 ? cz - 16 : cz) / 16; - short dx = _x - (px < 0 ? px - 16 : px) / 16, dz = _z - (pz < 0 ? pz - 16 : pz) / 16; + short dx = _x - (player->x < 0 ? player->x - 16 : player->x) / 16, dz = _z - (player->z < 0 ? player->z - 16 : player->z) / 16; if (dx != 0 || dz != 0) { @@ -157,8 +153,13 @@ void handlePacket (int client_fd, int length, int packet_id) { } - if (packet_id == 0x1D) savePlayerPosition(client_fd, cx, cy, cz); - else savePlayerPositionAndRotation(client_fd, cx, cy, cz, yaw / 180.0f * 127.0f, pitch / 90.0f * 127.0f); + player->x = cx; + player->y = cy; + player->z = cz; + if (packet_id == 0x1E) { + player->yaw = yaw / 180.0f * 127.0f; + player->pitch = pitch / 90.0f * 127.0f; + } return; } @@ -197,7 +198,9 @@ void handlePacket (int client_fd, int length, int packet_id) { int main () { - memset(block_changes, 0xFF, sizeof(block_changes)); + for (int i = 0; i < sizeof(block_changes) / sizeof(BlockChange); i ++) { + block_changes[i].block = 0xFF; + } int server_fd, client_fd, opt = 1; struct sockaddr_in server_addr, client_addr; diff --git a/src/globals.c b/src/globals.c index d02ab2f..b515cdc 100644 --- a/src/globals.c +++ b/src/globals.c @@ -9,17 +9,8 @@ ssize_t recv_count; uint8_t recv_buffer[256] = {0}; uint32_t world_seed = 0xA103DE6C; -uint8_t block_changes[50 * 1024]; + +BlockChange block_changes[20000]; int block_changes_count = 0; -uint8_t player_data[( - 16 + // UUID - 4 + // File descriptor - 2 + // X position (short) - 2 + // Y position (short) - 2 + // Z position (short) - 2 + // Angles (both, i8) - 1 + // Hotbar slot - 123 // Inventory (u16 id, u8 count) -) * MAX_PLAYERS]; -int player_data_size = 16 + 4 + 2 + 2 + 2 + 2 + 1 + 123; +PlayerData player_data[MAX_PLAYERS]; diff --git a/src/globals.h b/src/globals.h index bcf75d7..b88b1dc 100644 --- a/src/globals.h +++ b/src/globals.h @@ -21,19 +21,34 @@ extern ssize_t recv_count; extern uint8_t recv_buffer[256]; extern uint32_t world_seed; -extern uint8_t block_changes[50 * 1024]; + +#pragma pack(push, 1) + +typedef struct { + short x; + short y; + short z; + uint8_t block; +} BlockChange; + +typedef struct { + uint8_t uuid[16]; + int client_fd; + short x; + short y; + short z; + uint8_t yaw; + uint8_t pitch; + uint8_t hotbar; + uint16_t inventory_items[41]; + uint8_t inventory_count[41]; +} PlayerData; + +#pragma pack(pop) + +extern BlockChange block_changes[20000]; extern int block_changes_count; -extern uint8_t player_data[( - 16 + // UUID - 4 + // File descriptor - 2 + // X position (short) - 2 + // Y position (short) - 2 + // Z position (short) - 2 + // Angles (both, i8) - 1 + // Hotbar slot - 123 // Inventory (u16 id, u8 count) -) * MAX_PLAYERS]; -extern int player_data_size; +extern PlayerData player_data[MAX_PLAYERS]; #endif diff --git a/src/packets.c b/src/packets.c index 0bb0b1d..0fbb2af 100644 --- a/src/packets.c +++ b/src/packets.c @@ -370,33 +370,9 @@ int cs_playerAction (int client_fd) { else item = 0; } else item = B_to_I[block]; - uint8_t *inventory = getPlayerInventory(client_fd); - makeBlockChange(x, y, z, 0); - int slot_pair = -1; - for (int i = 0; i < 36 * 3; i += 3) { - memcpy(&tmp, inventory + i, 2); - if (tmp == item && inventory[i+2] < 64) { - slot_pair = i; - break; - } - } - - if (slot_pair == -1) { - for (int i = 0; i < 36 * 3; i += 3) { - if ((inventory[i] == 0 && inventory[i + 1] == 0) || inventory[i+2] == 0) { - slot_pair = i; - break; - } - } - } - - if (item && slot_pair != -1) { - uint8_t slot = serverSlotToClientSlot(slot_pair / 3); - memcpy(inventory + slot_pair, &item, 2); - sc_setContainerSlot(client_fd, 0, slot, ++inventory[slot_pair + 2], item); - } + if (item) givePlayerItem(client_fd, item); } @@ -427,24 +403,20 @@ int cs_useItemOn (int client_fd) { int sequence = readVarInt(client_fd); - // first, get pointer to player inventory - uint8_t *inventory = getPlayerInventory(client_fd); - // then, get pointer to selected hotbar slot - // the hotbar position is in address (inventory - 1) - uint8_t *slot = inventory + (*(inventory - 1)) * 3; - // the inventory is split into id-amount pairs, get the amount address - uint8_t *amount = slot + 2; - // convert the item id to a block id - uint8_t block = I_to_B[*(uint16_t *)slot]; + PlayerData *player; + if (getPlayerData(client_fd, &player)) return 1; + + uint8_t block = I_to_B[player->inventory_items[player->hotbar]]; // if the selected item doesn't correspond to a block, exit if (block == 0) return 0; // if the selected slot doesn't hold any items, exit - if (*amount == 0) return 0; + if (player->inventory_count[player->hotbar] == 0) return 0; // decrease item amount in selected slot - *amount = *amount - 1; + player->inventory_count[player->hotbar] --; // clear item id in slot if amount is zero - if (*amount == 0) *slot = 0; + if (player->inventory_count[player->hotbar] == 0) + player->inventory_items[player->hotbar] = 0; switch (face) { case 0: makeBlockChange(x, y - 1, z, block); break; @@ -471,7 +443,9 @@ int cs_clickContainer (int client_fd) { int changes_count = readVarInt(client_fd); - uint8_t *inventory = getPlayerInventory(client_fd); + PlayerData *player; + if (getPlayerData(client_fd, &player)) return 1; + uint8_t slot, count; uint16_t item; int tmp; @@ -482,9 +456,8 @@ int cs_clickContainer (int client_fd) { if (!readByte(client_fd)) { // no item? if (slot != 255) { - inventory[slot * 3] = 0; - inventory[slot * 3 + 1] = 0; - inventory[slot * 3 + 2] = 0; + player->inventory_items[slot] = 0; + player->inventory_count[slot] = 0; } continue; } @@ -499,8 +472,8 @@ int cs_clickContainer (int client_fd) { recv(client_fd, recv_buffer, tmp, MSG_WAITALL); if (item <= 255 && count > 0) { - memcpy(inventory + slot * 3, &item, 2); - inventory[slot * 3 + 2] = count; + player->inventory_items[slot] = item; + player->inventory_count[slot] = count; } } @@ -543,8 +516,10 @@ int cs_setPlayerPosition (int client_fd, double *x, double *y, double *z) { // C->S Set Held Item (serverbound) int cs_setHeldItem (int client_fd) { - uint8_t *hotbar = getPlayerInventory(client_fd) - 1; - *hotbar = (uint8_t)readUint16(client_fd); + PlayerData *player; + if (getPlayerData(client_fd, &player)) return 1; + + player->hotbar = (uint8_t)readUint16(client_fd); return 0; } diff --git a/src/tools.c b/src/tools.c index b5929d7..6cfdcad 100644 --- a/src/tools.c +++ b/src/tools.c @@ -6,6 +6,7 @@ #include "globals.h" #include "varnum.h" +#include "packets.h" static uint64_t htonll (uint64_t value) { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ @@ -128,19 +129,24 @@ int getClientIndex (int client_fd) { int reservePlayerData (int client_fd, char *uuid) { - uint64_t tmp; for (int i = 0; i < MAX_PLAYERS; i ++) { - memcpy(&tmp, player_data + i * player_data_size, 8); - if (memcmp(&tmp, uuid, 8) == 0) { - memcpy(player_data + i * player_data_size + 16, &client_fd, 4); + if (memcmp(player_data[i].uuid, uuid, 16) == 0) { + player_data[i].client_fd = client_fd; return 0; } - if (tmp == 0) { - memcpy(player_data + i * player_data_size, uuid, 16); - memcpy(player_data + i * player_data_size + 16, &client_fd, 4); - player_data[i * player_data_size + 20] = 8; - player_data[i * player_data_size + 22] = 80; - player_data[i * player_data_size + 24] = 8; + uint8_t empty = true; + for (uint8_t j = 0; j < 16; j ++) { + if (player_data[i].uuid[j] != 0) { + empty = false; + break; + } + } + if (empty) { + player_data[i].client_fd = client_fd; + memcpy(player_data[i].uuid, uuid, 16); + player_data[i].x = 8; + player_data[i].y = 80; + player_data[i].z = 8; return 0; } } @@ -149,91 +155,23 @@ int reservePlayerData (int client_fd, char *uuid) { } +int getPlayerData (int client_fd, PlayerData **output) { + for (int i = 0; i < MAX_PLAYERS; i ++) { + if (player_data[i].client_fd == client_fd) { + *output = &player_data[i]; + return 0; + } + } + return 1; +} + void clearPlayerFD (int client_fd) { - - int tmp; for (int i = 0; i < MAX_PLAYERS; i ++) { - memcpy(&tmp, player_data + i * player_data_size + 16, 4); - if (tmp == client_fd) { - tmp = 0; - memcpy(player_data + i * player_data_size + 16, &tmp, 4); - break; + if (player_data[i].client_fd == client_fd) { + player_data[i].client_fd = 0; + return; } } - -} - -int savePlayerPosition (int client_fd, short x, short y, short z) { - - int tmp; - for (int i = 0; i < MAX_PLAYERS; i ++) { - if (memcmp(&client_fd, player_data + i * player_data_size + 16, 4) == 0) { - - memcpy(player_data + i * player_data_size + 20, &x, 2); - memcpy(player_data + i * player_data_size + 22, &y, 2); - memcpy(player_data + i * player_data_size + 24, &z, 2); - - return 0; - } - } - - return 1; - -} - -int savePlayerPositionAndRotation (int client_fd, short x, short y, short z, int8_t yaw, int8_t pitch) { - - int tmp; - for (int i = 0; i < MAX_PLAYERS; i ++) { - if (memcmp(&client_fd, player_data + i * player_data_size + 16, 4) == 0) { - - memcpy(player_data + i * player_data_size + 20, &x, 2); - memcpy(player_data + i * player_data_size + 22, &y, 2); - memcpy(player_data + i * player_data_size + 24, &z, 2); - - memcpy(player_data + i * player_data_size + 26, &yaw, 1); - memcpy(player_data + i * player_data_size + 27, &pitch, 1); - - return 0; - } - } - - return 1; - -} - -int restorePlayerPosition (int client_fd, short *x, short *y, short *z, int8_t *yaw, int8_t *pitch) { - - int tmp; - for (int i = 0; i < MAX_PLAYERS; i ++) { - if (memcmp(&client_fd, player_data + i * player_data_size + 16, 4) == 0) { - - memcpy(x, player_data + i * player_data_size + 20, 2); - memcpy(y, player_data + i * player_data_size + 22, 2); - memcpy(z, player_data + i * player_data_size + 24, 2); - - if (yaw != NULL) memcpy(yaw, player_data + i * player_data_size + 26, 1); - if (pitch != NULL) memcpy(pitch, player_data + i * player_data_size + 27, 1); - - return 0; - } - } - - return 1; - -} - -uint8_t *getPlayerInventory (int client_fd) { - - int tmp; - for (int i = 0; i < MAX_PLAYERS; i ++) { - if (memcmp(&client_fd, player_data + i * player_data_size + 16, 4) == 0) { - return player_data + i * player_data_size + 29; - } - } - - return NULL; - } uint8_t serverSlotToClientSlot (uint8_t slot) { @@ -249,17 +187,47 @@ uint8_t clientSlotToServerSlot (uint8_t slot) { return 255; } +int givePlayerItem (int client_fd, uint16_t item) { + + PlayerData *player; + if (getPlayerData(client_fd, &player)) return 1; + + uint8_t slot = 255; + for (int i = 0; i < 41; i ++) { + if (player->inventory_items[i] == item && player->inventory_count[i] < 64) { + slot = i; + break; + } + } + + if (slot == 255) { + for (int i = 0; i < 41; i ++) { + if (player->inventory_items[i] == 0 && player->inventory_count[i] == 0) { + slot = i; + break; + } + } + } + + if (slot == 255) return 1; + + player->inventory_items[slot] = item; + player->inventory_count[slot] ++; + sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(slot), player->inventory_count[slot], item); + + return 0; + +} + uint8_t getBlockChange (short x, short y, short z) { short tmp; - for (int i = 0; i < block_changes_count * 7; i += 7) { - if (block_changes[i + 6] == 0xFF) continue; - memcpy(&tmp, block_changes + i, 2); - if (x != tmp) continue; - memcpy(&tmp, block_changes + i + 2, 2); - if (y != tmp) continue; - memcpy(&tmp, block_changes + i + 4, 2); - if (z != tmp) continue; - return block_changes[i + 6]; + for (int i = 0; i < block_changes_count; i ++) { + if (block_changes[i].block == 0xFF) continue; + if ( + block_changes[i].x == x && + block_changes[i].y == y && + block_changes[i].z == z + ) return block_changes[i].block; } return 0xFF; } @@ -267,22 +235,21 @@ uint8_t getBlockChange (short x, short y, short z) { void makeBlockChange (short x, short y, short z, uint8_t block) { short tmp; - for (int i = 0; i < block_changes_count * 7; i += 7) { - memcpy(&tmp, block_changes + i, 2); - if (x != tmp) continue; - memcpy(&tmp, block_changes + i + 2, 2); - if (y != tmp) continue; - memcpy(&tmp, block_changes + i + 4, 2); - if (z != tmp) continue; - block_changes[i + 6] = block; - return; + for (int i = 0; i < block_changes_count; i ++) { + if ( + block_changes[i].x == x && + block_changes[i].y == y && + block_changes[i].z == z + ) { + block_changes[i].block = block; + return; + } } - int end = block_changes_count * 7; - memcpy(block_changes + end, &x, 2); - memcpy(block_changes + end + 2, &y, 2); - memcpy(block_changes + end + 4, &z, 2); - block_changes[end + 6] = block; + block_changes[block_changes_count].x = x; + block_changes[block_changes_count].y = y; + block_changes[block_changes_count].z = z; + block_changes[block_changes_count].block = block; block_changes_count ++; } diff --git a/src/tools.h b/src/tools.h index 3be68e2..5cd0d90 100644 --- a/src/tools.h +++ b/src/tools.h @@ -32,11 +32,9 @@ int getClientState (int client_fd); int getClientIndex (int client_fd); int reservePlayerData (int client_fd, char *uuid); +int getPlayerData (int client_fd, PlayerData **output); void clearPlayerFD (int client_fd); -int savePlayerPositionAndRotation (int client_fd, short x, short y, short z, int8_t yaw, int8_t pitch); -int savePlayerPosition (int client_fd, short x, short y, short z); -int restorePlayerPosition (int client_fd, short *x, short *y, short *z, int8_t *yaw, int8_t *pitch); -uint8_t *getPlayerInventory (int client_fd); +int givePlayerItem (int client_fd, uint16_t item); uint8_t serverSlotToClientSlot (uint8_t slot); uint8_t clientSlotToServerSlot (uint8_t slot);