summaryrefslogtreecommitdiffstats
path: root/package.h
blob: e62cb04871035cf8c315d19fbca7909e8bff72a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//
//  package.h
//  mcc@exe
//
//  Created by Finn Behrens on 27.02.21.
//

#ifndef package_h
#define package_h

#include <stdio.h>
#include <stdlib.h>
#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 */