From d27b085ae527b3d0cab7460d01a16c61e597c21b Mon Sep 17 00:00:00 2001 From: p2r3 Date: Sun, 17 Aug 2025 19:24:31 +0300 Subject: [PATCH] return items to inventory when closing crafting window --- src/main.c | 9 ++++++++- src/packets.c | 26 +++++++++++++++++++++++++- src/packets.h | 1 + src/tools.c | 40 +++++++++++++++++++++++++++------------- src/tools.h | 4 ++-- 5 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/main.c b/src/main.c index 63a1faf..d3e5f58 100644 --- a/src/main.c +++ b/src/main.c @@ -94,7 +94,7 @@ void handlePacket (int client_fd, int length, int packet_id) { sc_synchronizePlayerPosition(client_fd, spawn_x, spawn_y, spawn_z, spawn_yaw, spawn_pitch); for (uint8_t i = 0; i < 41; i ++) { - sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(i), player->inventory_count[i], player->inventory_items[i]); + sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(0, i), player->inventory_count[i], player->inventory_items[i]); } sc_setHeldItem(client_fd, player->hotbar); @@ -146,6 +146,13 @@ void handlePacket (int client_fd, int length, int packet_id) { } break; + case 0x12: + if (state == STATE_PLAY) { + cs_closeContainer(client_fd); + return; + } + break; + case 0x1D: case 0x1E: if (state == STATE_PLAY) { diff --git a/src/packets.c b/src/packets.c index f52c901..fb19f9e 100644 --- a/src/packets.c +++ b/src/packets.c @@ -430,7 +430,11 @@ int cs_playerAction (int client_fd) { makeBlockChange(x, y, z, 0); - if (item) givePlayerItem(client_fd, item); + if (item) { + PlayerData *player; + if (getPlayerData(client_fd, &player)) return 1; + givePlayerItem(player, item, 1); + } } @@ -643,6 +647,26 @@ int sc_setHeldItem (int client_fd, uint8_t slot) { return 0; } +// C->S Close Container (serverbound) +int cs_closeContainer (int client_fd) { + + uint8_t window_id = readVarInt(client_fd); + + PlayerData *player; + if (getPlayerData(client_fd, &player)) return 1; + + // return all items in crafting slots to the player + for (uint8_t i = 0; i < 9; i ++) { + givePlayerItem(player, player->craft_items[i], player->craft_count[i]); + player->craft_items[i] = 0; + player->craft_count[i] = 0; + uint8_t client_slot = serverSlotToClientSlot(window_id, 41 + i); + if (client_slot != 255) sc_setContainerSlot(player->client_fd, 0, client_slot, 0, 0); + } + + return 0; +} + // S->C Registry Data (multiple packets) and Update Tags (configuration, multiple packets) int sc_registries (int client_fd) { diff --git a/src/packets.h b/src/packets.h index 6424d7f..6f27f3e 100644 --- a/src/packets.h +++ b/src/packets.h @@ -11,6 +11,7 @@ int cs_setPlayerPositionAndRotation (int client_fd, double *x, double *y, double int cs_setPlayerPosition (int client_fd, double *x, double *y, double *z); int cs_setHeldItem (int client_fd); int cs_clickContainer (int client_fd); +int cs_closeContainer (int client_fd); int sc_loginSuccess (int client_fd, char *name, char *uuid); int sc_knownPacks (int client_fd); diff --git a/src/tools.c b/src/tools.c index a2f6e87..2989706 100644 --- a/src/tools.c +++ b/src/tools.c @@ -194,11 +194,28 @@ void clearPlayerFD (int client_fd) { } } -uint8_t serverSlotToClientSlot (uint8_t slot) { - if (slot < 9) return slot + 36; - if (slot >= 9 && slot <= 35) return slot; - if (slot == 40) return 45; - if (slot >= 36 && slot <= 39) return 3 - (slot - 36) + 5; +uint8_t serverSlotToClientSlot (int window_id, uint8_t slot) { + + if (window_id == 0) { // player inventory + + if (slot < 9) return slot + 36; + if (slot >= 9 && slot <= 35) return slot; + if (slot == 40) return 45; + if (slot >= 36 && slot <= 39) return 3 - (slot - 36) + 5; + if (slot >= 41 && slot <= 44) return slot - 40; + + } else if (window_id == 12) { // crafting table + + if (slot >= 41 && slot <= 49) return slot - 40; + return serverSlotToClientSlot(0, slot - 1); + + } else if (window_id == 14) { // furnace + + if (slot >= 41 && slot <= 43) return slot - 41; + return serverSlotToClientSlot(0, slot + 6); + + } + return 255; } @@ -238,14 +255,11 @@ uint8_t clientSlotToServerSlot (int window_id, uint8_t slot) { return 255; } -int givePlayerItem (int client_fd, uint16_t item) { - - PlayerData *player; - if (getPlayerData(client_fd, &player)) return 1; +int givePlayerItem (PlayerData *player, uint16_t item, uint8_t count) { uint8_t slot = 255; for (int i = 0; i < 41; i ++) { - if (player->inventory_items[i] == item && player->inventory_count[i] < 64) { + if (player->inventory_items[i] == item && player->inventory_count[i] <= 64 - count) { slot = i; break; } @@ -263,8 +277,8 @@ int givePlayerItem (int client_fd, uint16_t item) { 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); + player->inventory_count[slot] += count; + sc_setContainerSlot(player->client_fd, 0, serverSlotToClientSlot(0, slot), player->inventory_count[slot], item); return 0; @@ -324,7 +338,7 @@ uint16_t getMiningResult (int client_fd, uint8_t block) { ) { player->inventory_items[player->hotbar] = 0; player->inventory_count[player->hotbar] = 0; - sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(player->hotbar), 0, 0); + sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(0, player->hotbar), 0, 0); } switch (block) { diff --git a/src/tools.h b/src/tools.h index 900fe17..b30f070 100644 --- a/src/tools.h +++ b/src/tools.h @@ -35,9 +35,9 @@ 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 givePlayerItem (int client_fd, uint16_t item); +int givePlayerItem (PlayerData *player, uint16_t item, uint8_t count); -uint8_t serverSlotToClientSlot (uint8_t slot); +uint8_t serverSlotToClientSlot (int window_id, uint8_t slot); uint8_t clientSlotToServerSlot (int window_id, uint8_t slot); uint8_t getBlockChange (short x, short y, short z);