forked from EXTERNAL/bareiron
prevent players from dropping and losing items
This commit is contained in:
@@ -91,8 +91,10 @@ typedef struct {
|
|||||||
uint8_t hotbar;
|
uint8_t hotbar;
|
||||||
uint16_t inventory_items[41];
|
uint16_t inventory_items[41];
|
||||||
uint16_t craft_items[9];
|
uint16_t craft_items[9];
|
||||||
|
uint16_t cursor_item;
|
||||||
uint8_t inventory_count[41];
|
uint8_t inventory_count[41];
|
||||||
uint8_t craft_count[9];
|
uint8_t craft_count[9];
|
||||||
|
uint8_t cursor_count;
|
||||||
// 0x01 - attack cooldown
|
// 0x01 - attack cooldown
|
||||||
// 0x02 - has not spawned yet
|
// 0x02 - has not spawned yet
|
||||||
// 0x04 - sneaking
|
// 0x04 - sneaking
|
||||||
|
@@ -32,6 +32,7 @@ int sc_setCenterChunk (int client_fd, int x, int y);
|
|||||||
int sc_chunkDataAndUpdateLight (int client_fd, int _x, int _z);
|
int sc_chunkDataAndUpdateLight (int client_fd, int _x, int _z);
|
||||||
int sc_keepAlive (int client_fd);
|
int sc_keepAlive (int client_fd);
|
||||||
int sc_setContainerSlot (int client_fd, int window_id, uint16_t slot, uint8_t count, uint16_t item);
|
int sc_setContainerSlot (int client_fd, int window_id, uint16_t slot, uint8_t count, uint16_t item);
|
||||||
|
int sc_setCursorItem (int client_fd, uint16_t item, uint8_t count);
|
||||||
int sc_setHeldItem (int client_fd, uint8_t slot);
|
int sc_setHeldItem (int client_fd, uint8_t slot);
|
||||||
int sc_blockUpdate (int client_fd, int64_t x, int64_t y, int64_t z, uint8_t block);
|
int sc_blockUpdate (int client_fd, int64_t x, int64_t y, int64_t z, uint8_t block);
|
||||||
int sc_openScreen (int client_fd, uint8_t window, const char *title, uint16_t length);
|
int sc_openScreen (int client_fd, uint8_t window, const char *title, uint16_t length);
|
||||||
|
@@ -26,6 +26,7 @@ ssize_t writeDouble (int client_fd, double num);
|
|||||||
|
|
||||||
uint8_t readByte (int client_fd);
|
uint8_t readByte (int client_fd);
|
||||||
uint16_t readUint16 (int client_fd);
|
uint16_t readUint16 (int client_fd);
|
||||||
|
int16_t readInt16 (int client_fd);
|
||||||
uint32_t readUint32 (int client_fd);
|
uint32_t readUint32 (int client_fd);
|
||||||
uint64_t readUint64 (int client_fd);
|
uint64_t readUint64 (int client_fd);
|
||||||
int64_t readInt64 (int client_fd);
|
int64_t readInt64 (int client_fd);
|
||||||
|
@@ -504,15 +504,37 @@ int cs_clickContainer (int client_fd) {
|
|||||||
int window_id = readVarInt(client_fd);
|
int window_id = readVarInt(client_fd);
|
||||||
|
|
||||||
readVarInt(client_fd); // ignore state id
|
readVarInt(client_fd); // ignore state id
|
||||||
readUint16(client_fd); // ignore clicked slot number
|
|
||||||
readByte(client_fd); // ignore button
|
int16_t clicked_slot = readInt16(client_fd);
|
||||||
readVarInt(client_fd); // ignore operation mode
|
uint8_t button = readByte(client_fd);
|
||||||
|
uint8_t mode = readVarInt(client_fd);
|
||||||
|
|
||||||
int changes_count = readVarInt(client_fd);
|
int changes_count = readVarInt(client_fd);
|
||||||
|
|
||||||
PlayerData *player;
|
PlayerData *player;
|
||||||
if (getPlayerData(client_fd, &player)) return 1;
|
if (getPlayerData(client_fd, &player)) return 1;
|
||||||
|
|
||||||
|
uint8_t apply_changes = true;
|
||||||
|
// prevent dropping items
|
||||||
|
if (mode == 4 && clicked_slot != -999) {
|
||||||
|
// when using drop button, re-sync the respective slot
|
||||||
|
uint8_t slot = clientSlotToServerSlot(window_id, clicked_slot);
|
||||||
|
sc_setContainerSlot(client_fd, window_id, clicked_slot, player->inventory_count[slot], player->inventory_items[slot]);
|
||||||
|
apply_changes = false;
|
||||||
|
} else if (mode == 0 && clicked_slot == -999) {
|
||||||
|
// when clicking outside inventory, return the dropped item to the player
|
||||||
|
if (button == 0) {
|
||||||
|
givePlayerItem(player, player->cursor_item, player->cursor_count);
|
||||||
|
player->cursor_item = 0;
|
||||||
|
player->cursor_count = 0;
|
||||||
|
} else {
|
||||||
|
givePlayerItem(player, player->cursor_item, 1);
|
||||||
|
player->cursor_count -= 1;
|
||||||
|
if (player->cursor_count == 0) player->cursor_item = 0;
|
||||||
|
}
|
||||||
|
apply_changes = false;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t slot, count, craft = false;
|
uint8_t slot, count, craft = false;
|
||||||
uint16_t item;
|
uint16_t item;
|
||||||
int tmp;
|
int tmp;
|
||||||
@@ -521,10 +543,10 @@ int cs_clickContainer (int client_fd) {
|
|||||||
|
|
||||||
slot = clientSlotToServerSlot(window_id, readUint16(client_fd));
|
slot = clientSlotToServerSlot(window_id, readUint16(client_fd));
|
||||||
// slots outside of the inventory overflow into the crafting buffer
|
// slots outside of the inventory overflow into the crafting buffer
|
||||||
if (slot > 40) craft = true;
|
if (slot > 40 && apply_changes) craft = true;
|
||||||
|
|
||||||
if (!readByte(client_fd)) { // no item?
|
if (!readByte(client_fd)) { // no item?
|
||||||
if (slot != 255) {
|
if (slot != 255 && apply_changes) {
|
||||||
player->inventory_items[slot] = 0;
|
player->inventory_items[slot] = 0;
|
||||||
player->inventory_count[slot] = 0;
|
player->inventory_count[slot] = 0;
|
||||||
}
|
}
|
||||||
@@ -540,7 +562,7 @@ int cs_clickContainer (int client_fd) {
|
|||||||
tmp = readVarInt(client_fd);
|
tmp = readVarInt(client_fd);
|
||||||
recv_all(client_fd, recv_buffer, tmp, false);
|
recv_all(client_fd, recv_buffer, tmp, false);
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0 && apply_changes) {
|
||||||
player->inventory_items[slot] = item;
|
player->inventory_items[slot] = item;
|
||||||
player->inventory_count[slot] = count;
|
player->inventory_count[slot] = count;
|
||||||
}
|
}
|
||||||
@@ -558,20 +580,42 @@ int cs_clickContainer (int client_fd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read but ignore carried item slot (for now)
|
// assign cursor-carried item slot
|
||||||
if (readByte(client_fd)) {
|
if (readByte(client_fd)) {
|
||||||
readVarInt(client_fd);
|
player->cursor_item = readVarInt(client_fd);
|
||||||
readVarInt(client_fd);
|
player->cursor_count = readVarInt(client_fd);
|
||||||
|
// ignore components
|
||||||
tmp = readVarInt(client_fd);
|
tmp = readVarInt(client_fd);
|
||||||
recv_all(client_fd, recv_buffer, tmp, false);
|
recv_all(client_fd, recv_buffer, tmp, false);
|
||||||
tmp = readVarInt(client_fd);
|
tmp = readVarInt(client_fd);
|
||||||
recv_all(client_fd, recv_buffer, tmp, false);
|
recv_all(client_fd, recv_buffer, tmp, false);
|
||||||
|
} else {
|
||||||
|
player->cursor_item = 0;
|
||||||
|
player->cursor_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// S->C Set Cursor Item
|
||||||
|
int sc_setCursorItem (int client_fd, uint16_t item, uint8_t count) {
|
||||||
|
|
||||||
|
writeVarInt(client_fd, 1 + sizeVarInt(count) + (count != 0 ? sizeVarInt(item) + 2 : 0));
|
||||||
|
writeByte(client_fd, 0x59);
|
||||||
|
|
||||||
|
writeVarInt(client_fd, count);
|
||||||
|
if (count == 0) return 0;
|
||||||
|
|
||||||
|
writeVarInt(client_fd, item);
|
||||||
|
|
||||||
|
// Skip components
|
||||||
|
writeByte(client_fd, 0);
|
||||||
|
writeByte(client_fd, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// C->S Set Player Position And Rotation
|
// C->S Set Player Position And Rotation
|
||||||
int cs_setPlayerPositionAndRotation (int client_fd, double *x, double *y, double *z, float *yaw, float *pitch, uint8_t *on_ground) {
|
int cs_setPlayerPositionAndRotation (int client_fd, double *x, double *y, double *z, float *yaw, float *pitch, uint8_t *on_ground) {
|
||||||
|
|
||||||
@@ -656,6 +700,11 @@ int cs_closeContainer (int client_fd) {
|
|||||||
if (client_slot != 255) sc_setContainerSlot(player->client_fd, window_id, client_slot, 0, 0);
|
if (client_slot != 255) sc_setContainerSlot(player->client_fd, window_id, client_slot, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
givePlayerItem(player, player->cursor_item, player->cursor_count);
|
||||||
|
sc_setCursorItem(client_fd, 0, 0);
|
||||||
|
player->cursor_item = 0;
|
||||||
|
player->cursor_count = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -572,6 +572,20 @@ uint8_t getItemStackSize (uint16_t item) {
|
|||||||
|
|
||||||
void handlePlayerAction (PlayerData *player, int action, short x, short y, short z) {
|
void handlePlayerAction (PlayerData *player, int action, short x, short y, short z) {
|
||||||
|
|
||||||
|
// Re-sync slot when player drops an item
|
||||||
|
if (action == 3 || action == 4) {
|
||||||
|
sc_setContainerSlot(
|
||||||
|
player->client_fd, 0,
|
||||||
|
serverSlotToClientSlot(0, player->hotbar),
|
||||||
|
player->inventory_count[player->hotbar],
|
||||||
|
player->inventory_items[player->hotbar]
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore further actions not pertaining to mining blocks
|
||||||
|
if (action != 0 && action != 2) return;
|
||||||
|
|
||||||
// In creative, only the "start mining" action is sent
|
// In creative, only the "start mining" action is sent
|
||||||
// No additional verification is performed, the block is simply removed
|
// No additional verification is performed, the block is simply removed
|
||||||
if (action == 0 && GAMEMODE == 1) {
|
if (action == 0 && GAMEMODE == 1) {
|
||||||
@@ -579,9 +593,6 @@ void handlePlayerAction (PlayerData *player, int action, short x, short y, short
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore actions not pertaining to mining blocks
|
|
||||||
if (action != 0 && action != 2) return;
|
|
||||||
|
|
||||||
uint8_t block = getBlockAt(x, y, z);
|
uint8_t block = getBlockAt(x, y, z);
|
||||||
|
|
||||||
// If this is a "start mining" packet, the block must be instamine
|
// If this is a "start mining" packet, the block must be instamine
|
||||||
|
@@ -134,6 +134,10 @@ uint16_t readUint16 (int client_fd) {
|
|||||||
recv_count = recv_all(client_fd, recv_buffer, 2, false);
|
recv_count = recv_all(client_fd, recv_buffer, 2, false);
|
||||||
return ((uint16_t)recv_buffer[0] << 8) | recv_buffer[1];
|
return ((uint16_t)recv_buffer[0] << 8) | recv_buffer[1];
|
||||||
}
|
}
|
||||||
|
int16_t readInt16 (int client_fd) {
|
||||||
|
recv_count = recv_all(client_fd, recv_buffer, 2, false);
|
||||||
|
return ((int16_t)recv_buffer[0] << 8) | (int16_t)recv_buffer[1];
|
||||||
|
}
|
||||||
uint32_t readUint32 (int client_fd) {
|
uint32_t readUint32 (int client_fd) {
|
||||||
recv_count = recv_all(client_fd, recv_buffer, 4, false);
|
recv_count = recv_all(client_fd, recv_buffer, 4, false);
|
||||||
return ((uint32_t)recv_buffer[0] << 24) |
|
return ((uint32_t)recv_buffer[0] << 24) |
|
||||||
|
Reference in New Issue
Block a user