// // package.h // mcc@exe // // Created by Finn Behrens on 27.02.21. // #ifndef package_h #define package_h #include #include #include "protocol.h" void static inline print_hex(uint8_t *src, int size) { int j; for (j = 0; j < size; j++) { if (!(j % 10)) printf("\n%04x: ", j); else if (!(j % 5)) printf(" "); printf("0x%02x ", src[j]); } } enum mc_direction { MC_DIRCETION_SERVER, MC_DIRECTION_CLIENT, }; enum mc_state { MC_STATE_HANDSHAKE = 0, MC_STATE_STATUS = 1, MC_STATE_LOGIN = 2, MC_STATE_PLAY, }; enum mc_packet { MC_PACKET_HANDSHAKE = 0x00, MC_PACKET_PING = 0x01, MC_PACKET_LOGIN_SUCCESS = 0x02, MC_PACKET_JOIN_GAME = 0x25, MC_PACKET_PLAYER_INFO = 0x33, MC_PACKET_PLAYER_POSTITION = 0x35, }; enum mc_player_info_action { MC_PLAYER_INFO_ACTION_ADD, MC_PLAYER_INFO_ACTION_UPDATE_GAMEMODE, MC_PLAYER_INFO_ACTION_UPDATE_LATENCY, MC_PLAYER_INFO_ACTION_UPDATE_DISPLAY_NAME, MC_PLAYER_INFO_ACTION_REMOVE, }; enum mc_play_gamemode { MC_PLAY_GAMEMODE_SURVIVAL, MC_PLAY_GAMEMODE_CREATIVE, MC_PLAY_GAMEMODE_ADVENTURE, MC_PLAY_GAMEMODE_SPECTATOR, }; typedef struct mc_package_header { int length; enum mc_packet cmd; uint8_t *data; } mc_package_header_t; typedef struct mc_play_user { // uuid of the user uint8_t *uuid; char *name; enum mc_play_gamemode gamemode; int ping; char *display_name; // TODO: chat type? } mc_play_user_t; /// Print the hex representation of a package, without the length and id header /// @param header header of the mc_package void mc_package_print(mc_package_header_t *header); /// convert the message in header into the network presentation. /// This function allocates the buffer to write to /// @param header header of the mc_package /// @param buffer pointer the buffer to write into int mc_package_serialize(mc_package_header_t *header, uint8_t **buffer); /// Parse package from src and allocate a data file in the header /// @param header header of the mc_package /// @param src buffer to read from int mc_package_parse(mc_package_header_t *header, uint8_t *src); /// Create a new mc_package_header, with empty data mc_package_header_t *mc_package_new(); /// Free data field and header /// @param header header of the mc_package void mc_package_free(mc_package_header_t *header); /// data at offset /// @param header mc_package_header /// @param offset offset of the desired data static inline void *mc_package_data(mc_package_header_t *header, size_t offset) { return (uint8_t *)header->data + offset; } int mc_package_get_var_int(mc_package_header_t *header, size_t offset, int *size); char *mc_package_read_string(mc_package_header_t *header, size_t offset, int *size); static inline uint8_t mc_package_get_uint8(mc_package_header_t *header, size_t offset) { return *(uint8_t *) mc_package_data(header, offset); } static inline uint16_t mc_package_get_uint16(mc_package_header_t *header, size_t offset) { return BE16_TO_H(*(uint16_t *) mc_package_data(header, offset)); } int mc_package_put_var_int(mc_package_header_t *header, int data); int mc_package_put_string(mc_package_header_t *header, const char* str); int mc_package_put(mc_package_header_t *header, int size, const void *data); static inline int mc_package_put_bool(mc_package_header_t *header, bool v) { uint8_t d = v ? 0x01 : 0x00; return mc_package_put(header, 1, &d); } static inline int mc_package_put_u8(mc_package_header_t *header, uint8_t d) { return mc_package_put(header, sizeof(d), &d); } static inline int mc_package_put_i8(mc_package_header_t *header, int8_t d) { return mc_package_put(header, sizeof(d), &d); } static inline int mc_package_put_i32(mc_package_header_t *header, int32_t d) { int32_t v = H_TO_BE32(d); return mc_package_put(header, sizeof(v), &v); } static inline int mc_package_put_uuid(mc_package_header_t *header, void *d) { return mc_package_put(header, 16, d); } static inline int mc_package_put_float(mc_package_header_t *header, float d) { float v = H_TO_BE32(d); return mc_package_put(header, sizeof(float), &v); } static inline int mc_package_put_double(mc_package_header_t *header, double d) { double v = H_TO_BE64(d); return mc_package_put(header, sizeof(double), &v); } //(mc_package_put(h, 1, d ? 0x01 : 0x00)) #define mc_package_put_u16(h, d) (mc_package_put(h, sizeof(uint16_t), d #define mc_package_put_i16(h, d) (mc_package_put(h, sizeof(int16_t), d #define mc_package_put_u64(h, d) (mc_package_put(h, sizeof(uint64_t), d #define mc_package_put_i64(h, d) (mc_package_put(h, sizeof(int64_t), d /// create new user pointer mc_play_user_t *mc_play_user_new(); /// Get the first part of th uuid of the user as eid int /// @param user static inline int mc_play_user_get_eid(mc_play_user_t *user) { return *(int*)user->uuid; } /// free the user buffer, and every buffer in the user struct /// @param user user to free void mc_play_user_free(mc_play_user_t *user); /// append user to mc_package_header /// @param header package to add to /// @param user user to add /// @param action format to add int mc_package_put_user(mc_package_header_t *header, mc_play_user_t *user, int action); #endif /* package_h */