1
0
mirror of https://github.com/p2r3/bareiron.git synced 2025-10-02 07:35:08 +02:00
Files
bareiron/src/tools.c
2025-08-12 18:22:37 +03:00

278 lines
7.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "globals.h"
#include "varnum.h"
#include "packets.h"
#include "tools.h"
static uint64_t htonll (uint64_t value) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
return ((uint64_t)htonl((uint32_t)(value >> 32))) |
((uint64_t)htonl((uint32_t)(value & 0xFFFFFFFF)) << 32);
#else
return value;
#endif
}
ssize_t writeByte (int client_fd, uint8_t byte) {
return send(client_fd, &byte, 1, 0);
}
ssize_t writeUint16 (int client_fd, uint16_t num) {
uint16_t be = htons(num);
return send(client_fd, &be, sizeof(be), 0);
}
ssize_t writeUint32 (int client_fd, uint32_t num) {
uint32_t be = htonl(num);
return send(client_fd, &be, sizeof(be), 0);
}
ssize_t writeUint64 (int client_fd, uint64_t num) {
uint64_t be = htonll(num);
return send(client_fd, &be, sizeof(be), 0);
}
ssize_t writeFloat (int client_fd, float num) {
uint32_t bits;
memcpy(&bits, &num, sizeof(bits));
bits = htonl(bits);
return send(client_fd, &bits, sizeof(bits), 0);
}
ssize_t writeDouble (int client_fd, double num) {
uint64_t bits;
memcpy(&bits, &num, sizeof(bits));
bits = htonll(bits);
return send(client_fd, &bits, sizeof(bits), 0);
}
uint8_t readByte (int client_fd) {
recv_count = recv(client_fd, recv_buffer, 1, MSG_WAITALL);
return recv_buffer[0];
}
uint16_t readUint16 (int client_fd) {
recv_count = recv(client_fd, recv_buffer, 2, MSG_WAITALL);
return ((uint16_t)recv_buffer[0] << 8) | recv_buffer[1];
}
uint32_t readUint32 (int client_fd) {
recv_count = recv(client_fd, recv_buffer, 4, MSG_WAITALL);
return ((uint32_t)recv_buffer[0] << 24) |
((uint32_t)recv_buffer[1] << 16) |
((uint32_t)recv_buffer[2] << 8) |
((uint32_t)recv_buffer[3]);
}
uint64_t readUint64 (int client_fd) {
recv_count = recv(client_fd, recv_buffer, 8, MSG_WAITALL);
return ((uint64_t)recv_buffer[0] << 56) |
((uint64_t)recv_buffer[1] << 48) |
((uint64_t)recv_buffer[2] << 40) |
((uint64_t)recv_buffer[3] << 32) |
((uint64_t)recv_buffer[4] << 24) |
((uint64_t)recv_buffer[5] << 16) |
((uint64_t)recv_buffer[6] << 8) |
((uint64_t)recv_buffer[7]);
}
int64_t readInt64 (int client_fd) {
recv_count = recv(client_fd, recv_buffer, 8, MSG_WAITALL);
return ((int64_t)recv_buffer[0] << 56) |
((int64_t)recv_buffer[1] << 48) |
((int64_t)recv_buffer[2] << 40) |
((int64_t)recv_buffer[3] << 32) |
((int64_t)recv_buffer[4] << 24) |
((int64_t)recv_buffer[5] << 16) |
((int64_t)recv_buffer[6] << 8) |
((int64_t)recv_buffer[7]);
}
float readFloat (int client_fd) {
uint32_t bytes = readUint32(client_fd);
float output;
memcpy(&output, &bytes, sizeof(output));
return output;
}
double readDouble (int client_fd) {
uint64_t bytes = readUint64(client_fd);
double output;
memcpy(&output, &bytes, sizeof(output));
return output;
}
void readString (int client_fd) {
uint32_t length = readVarInt(client_fd);
recv_count = recv(client_fd, recv_buffer, length, MSG_WAITALL);
recv_buffer[recv_count] = '\0';
}
int client_states[MAX_PLAYERS * 2];
void setClientState (int client_fd, int new_state) {
for (int i = 0; i < MAX_PLAYERS * 2; i += 2) {
if (client_states[i] != client_fd && client_states[i] != 0) continue;
client_states[i] = client_fd;
client_states[i + 1] = new_state;
}
}
int getClientState (int client_fd) {
for (int i = 0; i < MAX_PLAYERS * 2; i += 2) {
if (client_states[i] != client_fd) continue;
return client_states[i + 1];
}
return STATE_NONE;
}
int getClientIndex (int client_fd) {
for (int i = 0; i < MAX_PLAYERS * 2; i += 2) {
if (client_states[i] != client_fd) continue;
return i;
}
return -1;
}
int reservePlayerData (int client_fd, char *uuid) {
for (int i = 0; i < MAX_PLAYERS; i ++) {
if (memcmp(player_data[i].uuid, uuid, 16) == 0) {
player_data[i].client_fd = client_fd;
return 0;
}
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].y = -32767;
return 0;
}
}
return 1;
}
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) {
for (int i = 0; i < MAX_PLAYERS; i ++) {
if (player_data[i].client_fd == client_fd) {
player_data[i].client_fd = 0;
return;
}
}
}
uint8_t serverSlotToClientSlot (uint8_t slot) {
if (slot >= 0 && 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;
return 255;
}
uint8_t clientSlotToServerSlot (int window_id, uint8_t slot) {
if (window_id == 0) { // player inventory
if (slot >= 36 && slot <= 44) return slot - 36;
if (slot >= 9 && slot <= 35) return slot;
if (slot == 45) return 40;
if (slot >= 5 && slot <= 8) return 4 - (slot - 5) + 36;
// map inventory crafting slots to player data crafting grid (semi-hack)
// this abuses the fact that the buffers are adjacent in player data
if (slot == 1) return 41;
if (slot == 2) return 42;
if (slot == 3) return 44;
if (slot == 4) return 45;
} else if (window_id == 12) { // crafting table
// same crafting offset overflow hack as above
if (slot >= 1 && slot <= 9) return 40 + slot;
// the rest of the slots are identical, just shifted by one
if (slot >= 10 && slot <= 45) return clientSlotToServerSlot(0, slot - 1);
}
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; 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;
}
void makeBlockChange (short x, short y, short z, uint8_t block) {
short tmp;
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;
}
}
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 ++;
}