nbt upgrade, more networking progress

This commit is contained in:
Protryon 2019-04-14 15:57:59 -07:00
parent 5c31a579db
commit 7f6fa031b6
14 changed files with 422 additions and 754 deletions

View File

@ -5,8 +5,11 @@
#ifndef BASIN_CONNECTION_H
#define BASIN_CONNECTION_H
#include <basin/player.h>
#include <basin/server.h>
#include <avuna/netmgr.h>
#include <avuna/pmem.h>
#include <netinet/in.h>
struct connection {
struct mempool* pool;
@ -27,7 +30,8 @@ struct connection {
EVP_CIPHER_CTX* aes_ctx_enc;
EVP_CIPHER_CTX* aes_ctx_dec;
uint32_t protocol_state;
ssize_t compression_state;
struct server* server;
};
#endif //BASIN_CONNECTION_H

View File

@ -8,6 +8,8 @@
#ifndef NBT_H_
#define NBT_H_
#include <avuna/hash.h>
#include <avuna/pmem.h>
#include <stdlib.h>
#include <stdint.h>
@ -23,47 +25,50 @@
#define NBT_TAG_LIST 9
#define NBT_TAG_COMPOUND 10
#define NBT_TAG_INTARRAY 11
#define NBT_TAG_LONGARRAY 12
union nbt_data {
signed char nbt_byte;
int16_t nbt_short;
int32_t nbt_int;
int64_t nbt_long;
float nbt_float;
double nbt_double;
struct {
int32_t len;
unsigned char* data;
} nbt_bytearray;
char* nbt_string;
struct {
unsigned char type;
int32_t count;
} nbt_list;
struct {
int32_t count;
int32_t* ints;
} nbt_intarray;
signed char nbt_byte;
int16_t nbt_short;
int32_t nbt_int;
int64_t nbt_long;
float nbt_float;
double nbt_double;
struct {
int32_t len;
unsigned char* data;
} nbt_bytearray;
char* nbt_string;
struct {
unsigned char type;
int32_t count;
} nbt_list;
struct {
int32_t count;
int32_t* ints;
} nbt_intarray;
struct {
int32_t count;
int64_t* longs;
} nbt_longarray;
};
struct nbt_tag {
unsigned char id;
char* name;
size_t children_count;
struct nbt_tag** children;
struct hashmap* children;
union nbt_data data;
struct mempool* pool;
};
ssize_t decompressNBT(void* data, size_t size, void** dest);
ssize_t nbt_decompress(struct mempool* pool, void* data, size_t size, void** dest);
void freeNBT(struct nbt_tag* nbt);
struct nbt_tag* nbt_clone(struct mempool* pool, struct nbt_tag* nbt);
struct nbt_tag* cloneNBT(struct nbt_tag* nbt);
struct nbt_tag* nbt_get(struct nbt_tag* nbt, char* name);
struct nbt_tag* getNBTChild(struct nbt_tag* nbt, char* name);
ssize_t nbt_read(struct mempool* pool, struct nbt_tag** root, unsigned char* buffer, size_t buflen);
int readNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen);
int writeNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen);
ssize_t nbt_write(struct nbt_tag* root, unsigned char* buffer, size_t buflen);
#endif /* NBT_H_ */

View File

@ -9,6 +9,7 @@
#define NETWORK_H_
#include <basin/inventory.h>
#include <avuna/pmem.h>
#include <openssl/rsa.h>
struct packet;
@ -49,21 +50,15 @@ int readVarInt(int32_t* output, unsigned char* buffer, size_t buflen);
int readVarLong(int64_t* output, unsigned char* buffer, size_t buflen);
int writeString(char* input, unsigned char* buffer, size_t buflen);
ssize_t writeString(char* input, unsigned char* buffer, size_t buflen);
int readString(char** output, unsigned char* buffer, size_t buflen);
int readString(struct mempool* pool, char** output, unsigned char* buffer, size_t buflen);
int readSlot(struct slot* slot, unsigned char* buffer, size_t buflen);
int readSlot(struct mempool* pool, struct slot* slot, unsigned char* buffer, size_t buflen);
int writeSlot(struct slot* slot, unsigned char* buffer, size_t buflen);
void duplicateSlot(struct slot* slot, struct slot* dup);
void duplicateNBT(struct nbt_tag* nbt, struct nbt_tag* dup);
ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct packet* packet);
ssize_t writePacket(struct conn* conn, struct packet* packet);
void duplicateSlot(struct mempool* pool, struct slot* slot, struct slot* dup);
int writeVarInt_stream(int32_t input,
#ifdef __MINGW32__

View File

@ -22,16 +22,15 @@
#include <netinet/tcp.h>
#include <netinet/in.h>
void run_accept(struct accept_param* param) {
void run_accept(struct server* server) {
static int one = 1;
static unsigned char onec = 1;
struct timeval timeout;
timeout.tv_sec = 60;
timeout.tv_usec = 0;
struct pollfd spfd;
spfd.events = POLLIN;
spfd.revents = 0;
spfd.fd = param->server_fd;
spfd.fd = server->fd;
while (1) {
struct mempool* pool = mempool_new();
struct connection* conn = pcalloc(pool, sizeof(struct connection));
@ -40,6 +39,8 @@ void run_accept(struct accept_param* param) {
conn->managed_conn = pcalloc(conn->pool, sizeof(struct netmgr_connection));
conn->managed_conn->pool = conn->pool;
conn->managed_conn->extra = conn;
conn->compression_state = -1;
conn->server = server;
buffer_init(&conn->managed_conn->read_buffer, conn->pool);
buffer_init(&conn->managed_conn->write_buffer, conn->pool);
if (poll(&spfd, 1, -1) < 0) {
@ -53,7 +54,7 @@ void run_accept(struct accept_param* param) {
break;
}
spfd.revents = 0;
int fd = accept(param->server_fd, (struct sockaddr*) &conn->addr, &conn->addrlen);
int fd = accept(server->fd, (struct sockaddr*) &conn->addr, &conn->addrlen);
if (fd < 0) {
if (errno == EAGAIN) continue;
printf("Error while accepting client: %s\n", strerror(errno));
@ -69,7 +70,7 @@ void run_accept(struct accept_param* param) {
close(fd);
continue;
}
queue_push(param->server->prepared_connections, conn);
queue_push(server->prepared_connections, conn);
}
pthread_cancel (pthread_self());
}

View File

@ -10,10 +10,6 @@
#include <basin/server.h>
struct accept_param {
struct server* server;
};
void run_accept(struct accept_param* param);
void run_accept(struct server* param);
#endif /* ACCEPT_H_ */

View File

@ -352,9 +352,9 @@ int onItemInteract_spawnegg(struct world* world, struct player* player, uint8_t
//if (getBlockWorld(world, x, y, z) != 0) return 0;
struct item_info* ii = getItemInfo(slot->item);
if (ii == NULL) return 0;
struct nbt_tag* et = getNBTChild(slot->nbt, "EntityTag");
struct nbt_tag* et = nbt_get(slot->nbt, "EntityTag");
if (et == NULL) return 0;
struct nbt_tag* tmp = getNBTChild(et, "id");
struct nbt_tag* tmp = nbt_get(et, "id");
if (tmp == NULL || tmp->id != NBT_TAG_STRING) return 0;
uint32_t etx = getIDFromEntityDataName(tmp->data.nbt_string);
struct entity* ent = newEntity(nextEntityID++, (float) x + .5, (float) y, (float) z + .5, etx, 0., 0.);

273
src/nbt.c
View File

@ -13,64 +13,47 @@
#include <zlib.h>
#include <stdio.h>
void freeNBT(struct nbt_tag* nbt) {
if (nbt->name != NULL) xfree(nbt->name);
if (nbt->children != NULL) {
for (size_t i = 0; i < nbt->children_count; i++) {
freeNBT(nbt->children[i]);
xfree(nbt->children[i]);
struct nbt_tag* nbt_get(struct nbt_tag* nbt, char* name) {
return hashmap_get(nbt->children, name);
}
struct nbt_tag* nbt_clone(struct mempool* pool, struct nbt_tag* nbt) {
struct nbt_tag* new_tag = pmalloc(pool, sizeof(struct nbt_tag));
new_tag->pool = pool;
new_tag->name = nbt->name == NULL ? NULL : xstrdup(nbt->name, 0);
new_tag->id = nbt->id;
new_tag->children = nbt->children == NULL ? NULL : hashmap_new(8, new_tag->pool);
memcpy(&new_tag->data, &nbt->data, sizeof(union nbt_data));
if (nbt->id == NBT_TAG_BYTEARRAY) {
new_tag->data.nbt_bytearray.data = pmalloc(new_tag->pool, (size_t) new_tag->data.nbt_bytearray.len);
memcpy(new_tag->data.nbt_bytearray.data, nbt->data.nbt_bytearray.data, (size_t) new_tag->data.nbt_bytearray.len);
} else if (nbt->id == NBT_TAG_STRING) {
new_tag->data.nbt_string = xstrdup(nbt->data.nbt_string, 0);
} else if (nbt->id == NBT_TAG_INTARRAY) {
new_tag->data.nbt_intarray.ints = pmalloc(new_tag->pool, new_tag->data.nbt_intarray.count * 4);
memcpy(new_tag->data.nbt_intarray.ints, nbt->data.nbt_intarray.ints, new_tag->data.nbt_intarray.count * 4);
} else if (nbt->id == NBT_TAG_LONGARRAY) {
new_tag->data.nbt_intarray.ints = pmalloc(new_tag->pool, new_tag->data.nbt_intarray.count * 4);
memcpy(new_tag->data.nbt_intarray.ints, nbt->data.nbt_intarray.ints, new_tag->data.nbt_intarray.count * 4);
}
if (new_tag->children != NULL) {
ITER_MAP(new_tag->children) {
struct nbt_tag* child = value;
bucket_entry->data = nbt_clone(pool, child);
ITER_MAP_END();
}
xfree(nbt->children);
}
if (nbt->id == NBT_TAG_BYTEARRAY) {
xfree(nbt->data.nbt_bytearray.data);
} else if (nbt->id == NBT_TAG_STRING) {
xfree(nbt->data.nbt_string);
} else if (nbt->id == NBT_TAG_INTARRAY) {
xfree(nbt->data.nbt_intarray.ints);
}
return new_tag;
}
struct nbt_tag* getNBTChild(struct nbt_tag* nbt, char* name) {
for (size_t i = 0; i < nbt->children_count; i++) {
if (streq_nocase(nbt->children[i]->name, name)) return nbt->children[i];
}
return NULL;
}
struct nbt_tag* cloneNBT(struct nbt_tag* nbt) {
struct nbt_tag* nt = xmalloc(sizeof(struct nbt_tag));
nt->name = nbt->name == NULL ? NULL : xstrdup(nbt->name, 0);
nt->id = nbt->id;
nt->children_count = nbt->children_count;
nt->children = nt->children_count == 0 ? NULL : xmalloc(sizeof(struct nbt_tag*) * nt->children_count);
memcpy(&nt->data, &nbt->data, sizeof(union nbt_data));
if (nbt->id == NBT_TAG_BYTEARRAY) {
nt->data.nbt_bytearray.data = xmalloc(nt->data.nbt_bytearray.len);
memcpy(nt->data.nbt_bytearray.data, nbt->data.nbt_bytearray.data, nt->data.nbt_bytearray.len);
} else if (nbt->id == NBT_TAG_STRING) {
nt->data.nbt_string = xstrdup(nbt->data.nbt_string, 0);
} else if (nbt->id == NBT_TAG_INTARRAY) {
nt->data.nbt_intarray.ints = xmalloc(nt->data.nbt_intarray.count * 4);
memcpy(nt->data.nbt_intarray.ints, nbt->data.nbt_intarray.ints, nt->data.nbt_intarray.count * 4);
}
for (size_t i = 0; i < nt->children_count; i++) {
nt->children[i] = cloneNBT(nbt->children[i]);
}
return nt;
}
int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen, int list) {
struct nbt_tag* cur = xmalloc(sizeof(struct nbt_tag));
cur->name = NULL;
cur->children = NULL;
cur->children_count = 0;
ssize_t __recurReadNBT(struct mempool* pool, struct nbt_tag** root, unsigned char* buffer, size_t buflen, int list) {
struct nbt_tag* cur = pcalloc(pool, sizeof(struct nbt_tag));
cur->pool = pool;
size_t r = 0;
if (list) {
cur->id = list;
cur->id = (unsigned char) list;
} else {
if (buflen < 1) {
xfree(cur);
return 0;
}
cur->id = buffer[0];
@ -80,7 +63,6 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
if (cur->id) {
uint16_t sl;
if (buflen < 2) {
free(cur);
return 0;
}
memcpy(&sl, buffer, 2);
@ -89,10 +71,9 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
r += 2;
buflen -= 2;
if (buflen < sl) {
xfree(cur);
return 0;
}
cur->name = xmalloc(sl + 1);
cur->name = pmalloc(pool, sl + 1);
cur->name[sl] = 0;
memcpy(cur->name, buffer, sl);
buffer += sl;
@ -102,8 +83,6 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
}
if (cur->id == NBT_TAG_BYTE) {
if (buflen < 1) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&cur->data.nbt_byte, buffer, 1);
@ -112,8 +91,6 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
r++;
} else if (cur->id == NBT_TAG_SHORT) {
if (buflen < 2) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&cur->data.nbt_short, buffer, 2);
@ -123,8 +100,6 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
r += 2;
} else if (cur->id == NBT_TAG_INT) {
if (buflen < 4) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&cur->data.nbt_int, buffer, 4);
@ -134,8 +109,6 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
r += 4;
} else if (cur->id == NBT_TAG_LONG) {
if (buflen < 8) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&cur->data.nbt_long, buffer, 8);
@ -145,8 +118,6 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
r += 8;
} else if (cur->id == NBT_TAG_FLOAT) {
if (buflen < 4) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&cur->data.nbt_float, buffer, 4);
@ -156,8 +127,6 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
r += 4;
} else if (cur->id == NBT_TAG_DOUBLE) {
if (buflen < 8) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&cur->data.nbt_double, buffer, 8);
@ -167,8 +136,6 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
r += 8;
} else if (cur->id == NBT_TAG_BYTEARRAY) {
if (buflen < 4) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&cur->data.nbt_bytearray.len, buffer, 4);
@ -177,20 +144,16 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
buflen -= 4;
r += 4;
if (buflen < cur->data.nbt_bytearray.len || cur->data.nbt_bytearray.len <= 0) {
xfree(cur->name);
xfree(cur);
return 0;
}
cur->data.nbt_bytearray.data = malloc(cur->data.nbt_bytearray.len);
memcpy(cur->data.nbt_bytearray.data, buffer, cur->data.nbt_bytearray.len);
cur->data.nbt_bytearray.data = pmalloc(pool, (size_t) cur->data.nbt_bytearray.len);
memcpy(cur->data.nbt_bytearray.data, buffer, (size_t) cur->data.nbt_bytearray.len);
buffer += cur->data.nbt_bytearray.len;
buflen -= cur->data.nbt_bytearray.len;
r += cur->data.nbt_bytearray.len;
} else if (cur->id == NBT_TAG_STRING) {
uint16_t sl;
if (buflen < 2) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&sl, buffer, 2);
@ -199,11 +162,9 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
r += 2;
buflen -= 2;
if (buflen < sl) {
xfree(cur->name);
xfree(cur);
return 0;
}
cur->data.nbt_string = xmalloc(sl + 1);
cur->data.nbt_string = pmalloc(pool, sl + 1);
cur->data.nbt_string[sl] = 0;
memcpy(cur->data.nbt_string, buffer, sl);
buffer += sl;
@ -226,51 +187,39 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
struct nbt_tag *st = NULL;
for (size_t i = 0; i < count; i++) {
st = NULL;
int nr = __recurReadNBT(&st, buffer, buflen, lt);
if (nr == 0) continue;
buffer += nr;
buflen -= nr;
r += nr;
ssize_t sub_read = __recurReadNBT(pool, &st, buffer, buflen, lt);
if (sub_read == 0) continue;
buffer += sub_read;
buflen -= sub_read;
r += sub_read;
if (!(st != NULL && st->id != NBT_TAG_END && buflen > 0)) {
if (st != NULL) freeNBT(st);
xfree(st);
st = NULL;
continue;
}
if (cur->children == NULL) {
cur->children = xmalloc(sizeof(struct nbt_tag*));
cur->children_count = 0;
} else {
cur->children = xrealloc(cur->children, sizeof(struct nbt_tag*) * (cur->children_count + 1));
cur->children = hashmap_new(8, pool);
}
cur->children[cur->children_count++] = st;
hashmap_put(cur->children, st->name, st);
}
} else if (cur->id == NBT_TAG_COMPOUND) {
struct nbt_tag *st = NULL;
do {
st = NULL;
int nr = __recurReadNBT(&st, buffer, buflen, 0);
buffer += nr;
buflen -= nr;
r += nr;
ssize_t sub_read = __recurReadNBT(pool, &st, buffer, buflen, 0);
buffer += sub_read;
buflen -= sub_read;
r += sub_read;
if (!(st != NULL && st->id != NBT_TAG_END && buflen > 0)) {
if (st != NULL) freeNBT(st);
xfree(st);
st = NULL;
continue;
}
if (cur->children == NULL) {
cur->children = xmalloc(sizeof(struct nbt_tag*));
cur->children_count = 0;
} else {
cur->children = xrealloc(cur->children, sizeof(struct nbt_tag*) * (cur->children_count + 1));
cur->children = hashmap_new(8, pool);
}
cur->children[cur->children_count++] = st;
hashmap_put(cur->children, st->name, st);
} while (st != NULL && st->id != NBT_TAG_END && buflen > 0);
} else if (cur->id == NBT_TAG_INTARRAY) {
if (buflen < 4) {
xfree(cur->name);
xfree(cur);
return 0;
}
memcpy(&cur->data.nbt_intarray.count, buffer, 4);
@ -278,24 +227,49 @@ int __recurReadNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen,
buffer += 4;
buflen -= 4;
r += 4;
if (buflen < (cur->data.nbt_intarray.count * 4) || cur->data.nbt_intarray.count <= 0) {
xfree(cur->name);
xfree(cur);
if (buflen < (cur->data.nbt_intarray.count * 4) || cur->data.nbt_intarray.count < 0) {
return 0;
}
cur->data.nbt_intarray.ints = xmalloc(cur->data.nbt_intarray.count * 4);
memcpy(cur->data.nbt_intarray.ints, buffer, cur->data.nbt_intarray.count * 4);
buffer += cur->data.nbt_intarray.count * 4;
buflen -= cur->data.nbt_intarray.count * 4;
r += cur->data.nbt_intarray.count * 4;
if (cur->data.nbt_intarray.count > 0) {
cur->data.nbt_intarray.ints = pmalloc(pool, cur->data.nbt_intarray.count * 4);
memcpy(cur->data.nbt_intarray.ints, buffer, cur->data.nbt_intarray.count * 4);
for (size_t i = 0; i < cur->data.nbt_intarray.count; i++) {
swapEndian(&cur->data.nbt_intarray.ints[i], 4);
}
buffer += cur->data.nbt_intarray.count * 4;
buflen -= cur->data.nbt_intarray.count * 4;
r += cur->data.nbt_intarray.count * 4;
}
} else if (cur->id == NBT_TAG_LONGARRAY) {
if (buflen < 4) {
return 0;
}
memcpy(&cur->data.nbt_longarray.count, buffer, 4);
swapEndian(&cur->data.nbt_longarray.count, 4);
buffer += 4;
buflen -= 4;
r += 4;
if (buflen < (cur->data.nbt_longarray.count * 8) || cur->data.nbt_longarray.count < 0) {
return 0;
}
if (cur->data.nbt_longarray.count > 0) {
cur->data.nbt_longarray.longs = pmalloc(pool, cur->data.nbt_longarray.count * 8);
memcpy(cur->data.nbt_longarray.longs, buffer, cur->data.nbt_longarray.count * 4);
for (size_t i = 0; i < cur->data.nbt_longarray.count; i++) {
swapEndian(&cur->data.nbt_longarray.longs[i], 4);
}
buffer += cur->data.nbt_longarray.count * 8;
buflen -= cur->data.nbt_longarray.count * 8;
r += cur->data.nbt_longarray.count * 8;
}
}
*root = cur;
return r;
}
#define DECOMPRESS_BUF_SIZE 16384
ssize_t decompressNBT(void* data, size_t size, void** dest) {
void* rtbuf = xmalloc(DECOMPRESS_BUF_SIZE);
ssize_t nbt_decompress(struct mempool* pool, void* data, size_t size, void** dest) {
void* rtbuf = pmalloc(pool, DECOMPRESS_BUF_SIZE);
size_t rtc = DECOMPRESS_BUF_SIZE;
z_stream strm;
strm.zalloc = Z_NULL;
@ -306,16 +280,15 @@ ssize_t decompressNBT(void* data, size_t size, void** dest) {
int dr = 0;
if ((dr = inflateInit2(&strm, (32 + MAX_WBITS))) != Z_OK) {
printf("Compression initialization error!\n");
xfree(rtbuf);
return -1;
}
strm.avail_in = size;
strm.avail_in = (uInt) size;
strm.next_in = data;
strm.avail_out = rtc;
strm.avail_out = (uInt) rtc;
strm.next_out = rtbuf;
do {
if (rtc - strm.total_out < DECOMPRESS_BUF_SIZE / 2) {
rtc += DECOMPRESS_BUF_SIZE;
rtc *= 2;
rtbuf = realloc(rtbuf, rtc);
}
strm.avail_out = rtc - strm.total_out;
@ -324,7 +297,6 @@ ssize_t decompressNBT(void* data, size_t size, void** dest) {
if (dr == Z_STREAM_ERROR) {
printf("Compression Read Error!\n");
inflateEnd(&strm);
xfree(rtbuf);
return -1;
}
} while (strm.avail_out == 0);
@ -333,14 +305,15 @@ ssize_t decompressNBT(void* data, size_t size, void** dest) {
return strm.total_out;
}
int readNBT(struct nbt_tag** root, unsigned char* buffer, size_t buflen) {
ssize_t nbt_read(struct mempool* pool, struct nbt_tag** root, unsigned char* buffer, size_t buflen) {
if (buflen == 0) return 0;
int x = __recurReadNBT(root, buffer, buflen, 0);
return x;
struct mempool* sub_pool = mempool_new();
pchild(pool, sub_pool);
return __recurReadNBT(sub_pool, root, buffer, buflen, 0);
}
int __recurWriteNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen, int list) {
size_t r = 0;
ssize_t __recurWriteNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen, int list) {
ssize_t r = 0;
if (list) {
} else {
@ -350,14 +323,14 @@ int __recurWriteNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen,
buffer++;
buflen--;
if (root->id > 0) {
int16_t sl = root->name == NULL ? 0 : strlen(root->name);
int16_t sl = (int16_t) (root->name == NULL ? 0 : strlen(root->name));
memcpy(buffer, &sl, 2);
swapEndian(buffer, 2);
r += 2;
buffer += 2;
buflen -= 2;
if (buflen < sl) return 0;
if (root->name != NULL) memcpy(buffer, root->name, sl);
if (root->name != NULL) memcpy(buffer, root->name, (size_t) sl);
r += sl;
buffer += sl;
buflen -= sl;
@ -365,7 +338,7 @@ int __recurWriteNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen,
}
if (root->id == NBT_TAG_BYTE) {
if (buflen < 1) return 0;
buffer[0] = root->data.nbt_byte;
buffer[0] = (unsigned char) root->data.nbt_byte;
r++;
buffer++;
buflen--;
@ -411,13 +384,13 @@ int __recurWriteNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen,
buffer += 4;
buflen -= 4;
if (buflen < root->data.nbt_bytearray.len) return 0;
memcpy(buffer, root->data.nbt_bytearray.data, root->data.nbt_bytearray.len);
memcpy(buffer, root->data.nbt_bytearray.data, (size_t) root->data.nbt_bytearray.len);
r += root->data.nbt_bytearray.len;
buffer += root->data.nbt_bytearray.len;
buflen -= root->data.nbt_bytearray.len;
} else if (root->id == NBT_TAG_STRING) {
if (buflen < 2) return 0;
uint16_t sl = strlen(root->data.nbt_string);
uint16_t sl = (uint16_t) strlen(root->data.nbt_string);
memcpy(buffer, &sl, 2);
swapEndian(buffer, 2);
r += 2;
@ -436,21 +409,25 @@ int __recurWriteNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen,
r += 5;
buffer += 5;
buflen -= 5;
for (size_t i = 0; i < root->children_count; i++) {
int x = __recurWriteNBT(root->children[i], buffer, buflen, 1);
r += x;
buffer += x;
buflen -= x;
if (buflen <= 0) break;
ITER_MAP(root->children) {
ssize_t sub_read = __recurWriteNBT(value, buffer, buflen, 1);
r += sub_read;
buffer += sub_read;
buflen -= sub_read;
if (buflen <= 0) goto break_iter_map;
ITER_MAP_END();
}
break_iter_map:;
} else if (root->id == NBT_TAG_COMPOUND) {
for (size_t i = 0; i < root->children_count; i++) {
int x = __recurWriteNBT(root->children[i], buffer, buflen, 0);
r += x;
buffer += x;
buflen -= x;
if (buflen <= 0) break;
ITER_MAP(root->children) {
ssize_t sub_read = __recurWriteNBT(value, buffer, buflen, 0);
r += sub_read;
buffer += sub_read;
buflen -= sub_read;
if (buflen <= 0) goto break_iter_map2;
ITER_MAP_END();
}
break_iter_map2:;
if (buflen <= 1) return 0;
buffer[0] = 0;
buffer++;
@ -465,14 +442,32 @@ int __recurWriteNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen,
buflen -= 4;
if (buflen < root->data.nbt_intarray.count * 4) return 0;
memcpy(buffer, root->data.nbt_intarray.ints, root->data.nbt_intarray.count * 4);
for (size_t i = 0; i < root->data.nbt_intarray.count; ++i) {
swapEndian(&root->data.nbt_intarray.ints[i], 4);
}
r += root->data.nbt_intarray.count * 4;
buffer += root->data.nbt_intarray.count * 4;
buflen -= root->data.nbt_intarray.count * 4;
} else if (root->id == NBT_TAG_LONGARRAY) {
if (buflen < 4) return 0;
memcpy(buffer, &root->data.nbt_longarray.count, 4);
swapEndian(buffer, 4);
r += 4;
buffer += 4;
buflen -= 4;
if (buflen < root->data.nbt_longarray.count * 8) return 0;
memcpy(buffer, root->data.nbt_longarray.longs, root->data.nbt_longarray.count * 8);
for (size_t i = 0; i < root->data.nbt_longarray.count; ++i) {
swapEndian(&root->data.nbt_longarray.longs[i], 8);
}
r += root->data.nbt_longarray.count * 8;
buffer += root->data.nbt_longarray.count * 8;
buflen -= root->data.nbt_longarray.count * 8;
}
return r;
}
int writeNBT(struct nbt_tag* root, unsigned char* buffer, size_t buflen) {
ssize_t nbt_write(struct nbt_tag* root, unsigned char* buffer, size_t buflen) {
if (buflen == 0) return 0;
return __recurWriteNBT(root, buffer, buflen, 0);
}

View File

@ -10,6 +10,7 @@
#include <basin/nbt.h>
#include <basin/network.h>
#include <avuna/pmem.h>
#include <avuna/string.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
@ -120,7 +121,7 @@ int readVarLong(int64_t* output, unsigned char* buffer, size_t buflen) {
return v2;
}
int writeString(char* input, unsigned char* buffer, size_t buflen) {
ssize_t writeString(char* input, unsigned char* buffer, size_t buflen) {
if (buflen < 4) return 0;
ssize_t sl = strlen(input);
if (sl - 4 > (ssize_t) buflen) {
@ -133,33 +134,33 @@ int writeString(char* input, unsigned char* buffer, size_t buflen) {
return sl + x;
}
int readString(char** output, unsigned char* buffer, size_t buflen) {
int readString(struct mempool* pool, char** output, unsigned char* buffer, size_t buflen) {
if (buflen < 1) {
*output = malloc(1);
*output = pmalloc(pool, 1);
(*output)[0] = 0;
return 0;
}
int32_t sl;
int x = readVarInt(&sl, buffer, buflen);
if (x == -1) {
*output = malloc(1);
*output = pmalloc(pool, 1);
(*output)[0] = 0;
return 0;
}
if (sl > 32767) {
*output = malloc(1);
*output = pmalloc(pool, 1);
(*output)[0] = 0;
return 0;
}
buflen -= x;
buffer += x;
if (buflen < sl) {
*output = malloc(1);
*output = pmalloc(pool, 1);
(*output)[0] = 0;
return 0;
}
*output = malloc(sl + 1);
memcpy(*output, buffer, sl);
*output = pmalloc(pool, (size_t) (sl + 1));
memcpy(*output, buffer, (size_t) sl);
(*output)[sl] = 0;
return x + sl; // silently ignores characters past the outlen
}
@ -216,18 +217,17 @@ int readVarInt_stream(int32_t* output,
return v2;
}
int readSlot(struct slot* slot, unsigned char* buffer, size_t buflen) {
int readSlot(struct mempool* pool, struct slot* slot, unsigned char* buffer, size_t buflen) {
if (buflen < 2) return -1;
memcpy(&slot->item, buffer, 2);
swapEndian(&slot->item, 2);
if (slot->item == -1) {
slot->damage = 0;
slot->itemCount = 0;
slot->nbt = malloc(sizeof(struct nbt_tag));
slot->nbt = pmalloc(pool, sizeof(struct nbt_tag));
slot->nbt->id = NBT_TAG_END;
slot->nbt->name = NULL;
slot->nbt->children = NULL;
slot->nbt->children_count = 0;
return 2;
}
buffer += 2;
@ -240,10 +240,10 @@ int readSlot(struct slot* slot, unsigned char* buffer, size_t buflen) {
swapEndian(&slot->damage, 2);
buffer += 2;
buflen -= 2;
return 5 + readNBT(&slot->nbt, buffer, buflen);
return 5 + nbt_read(&slot->nbt, buffer, buflen);
}
void duplicateSlot(struct slot* slot, struct slot* dup) {
void duplicateSlot(struct mempool* pool, struct slot* slot, struct slot* dup) {
if (slot == NULL) {
memset(dup, 0, sizeof(struct slot));
dup->item = -1;
@ -252,41 +252,10 @@ void duplicateSlot(struct slot* slot, struct slot* dup) {
dup->item = slot->item;
dup->damage = slot->damage;
dup->itemCount = slot->itemCount;
dup->nbt = xmalloc(sizeof(struct nbt_tag));
dup->nbt = pmalloc(struct mempool* pool, sizeof(struct nbt_tag));
duplicateNBT(slot->nbt, dup->nbt);
}
void duplicateNBT(struct nbt_tag* nbt, struct nbt_tag* dup) {
if (nbt == NULL) {
memset(dup, 0, sizeof(struct nbt_tag));
return;
}
dup->name = nbt->name == NULL ? NULL : xstrdup(nbt->name, 0);
dup->id = nbt->id;
dup->children_count = nbt->children_count;
if (dup->id == NBT_TAG_BYTE || dup->id == NBT_TAG_SHORT || dup->id == NBT_TAG_INT || dup->id == NBT_TAG_LONG || dup->id == NBT_TAG_FLOAT || dup->id == NBT_TAG_DOUBLE) {
memcpy(&dup->data, &nbt->data, sizeof(union nbt_data));
} else if (dup->id == NBT_TAG_BYTEARRAY) {
dup->data.nbt_bytearray.len = nbt->data.nbt_bytearray.len;
dup->data.nbt_bytearray.data = xmalloc(dup->data.nbt_bytearray.len);
memcpy(dup->data.nbt_bytearray.data, nbt->data.nbt_bytearray.data, dup->data.nbt_bytearray.len);
} else if (dup->id == NBT_TAG_STRING) {
dup->data.nbt_string = xstrdup(nbt->data.nbt_string, 0);
} else if (dup->id == NBT_TAG_LIST) {
dup->data.nbt_list.type = nbt->data.nbt_list.type;
dup->data.nbt_list.count = nbt->data.nbt_list.count;
} else if (dup->id == NBT_TAG_INTARRAY) {
dup->data.nbt_intarray.count = nbt->data.nbt_intarray.count;
dup->data.nbt_intarray.ints = xmalloc(4 * dup->data.nbt_intarray.count);
memcpy(dup->data.nbt_intarray.ints, nbt->data.nbt_intarray.ints, dup->data.nbt_bytearray.len);
}
dup->children = dup->children_count == 0 ? NULL : xmalloc(sizeof(struct nbt_tag*) * dup->children_count);
for (size_t i = 0; i < dup->children_count; i++) {
dup->children[i] = xmalloc(sizeof(struct nbt_tag));
duplicateNBT(nbt->children[i], dup->children[i]);
}
}
int writeSlot(struct slot* slot, unsigned char* buffer, size_t buflen) {
if (buflen < 2) return -1;
memcpy(buffer, &slot->item, 2);
@ -302,5 +271,5 @@ int writeSlot(struct slot* slot, unsigned char* buffer, size_t buflen) {
swapEndian(buffer, 2);
buffer += 2;
buflen -= 2;
return 5 + writeNBT(slot->nbt, buffer, buflen);
return 5 + nbt_write(slot->nbt, buffer, buflen);
}

View File

@ -1,95 +1,92 @@
#include <basin/globals.h>
#include "packet.h"
#include <basin/globals.h>
#include <basin/inventory.h>
#include <basin/network.h>
#include <basin/nbt.h>
#include <basin/connection.h>
#include <basin/world.h>
#include <basin/player.h>
#include <avuna/string.h>
#include <stdint.h>
#include "basin/network.h"
#include <zlib.h>
#include <errno.h>
#include <avuna/string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <basin/nbt.h>
#include <zlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include "accept.h"
#include "util.h"
#include <basin/world.h>
#include <math.h>
#include "packet.h"
#include <basin/player.h>
#define ADRX if(rx == 0) goto rer;pbuf += rx;ps -= rx;
#define ADX(x) pbuf += x;ps -= x;
#define CPS(x) if(ps < x) goto rer;
#define CPS_OPT(x) if(ps >= x) {
#define ENS(x) if(ps-pi < x) { ps += (x > 256 ? x + 1024 : 1024); pktbuf = prealloc(pktbuf - 10, ps + 10) + 10; }
#define ENS(x) if(ps-pi < x) { ps += (x > 256 ? x + 1024 : 1024); pktbuf = prealloc(packet->pool, pktbuf - 10, ps + 10) + 10; }
ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct packet* packet) {
ssize_t readPacket(struct connection* conn, unsigned char* buf, size_t buflen, struct packet* packet) {
void* pktbuf = buf;
int32_t pktlen = buflen;
int tf = 0;
if (conn->comp >= 0) {
int32_t dl = 0;
int rx = readVarInt(&dl, pktbuf, pktlen);
if (rx == 0) goto rer;
pktlen -= rx;
pktbuf += rx;
if (dl > 0 && pktlen > 0) {
pktlen = dl;
void* decmpbuf = xmalloc(dl);
int32_t pktlen = (int32_t) buflen;
if (conn->compression_state >= 0) {
int32_t decompressed_length = 0;
int read_length = readVarInt(&decompressed_length, pktbuf, buflen);
if (read_length == 0) goto rer;
pktlen -= read_length;
pktbuf += read_length;
if (decompressed_length > 0 && pktlen > 0) {
pktlen = decompressed_length;
void* decompressed = pmalloc(packet->pool, (size_t) decompressed_length);
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int dr = 0;
if ((dr = inflateInit(&strm)) != Z_OK) {
xfree(decmpbuf);
printf("Compression initialization error!\n");
errlog(conn->server->logger, "Compression initialization error!\n");
goto rer;
}
strm.avail_in = pktlen;
strm.avail_in = (uInt) pktlen;
strm.next_in = pktbuf;
strm.avail_out = dl;
strm.next_out = decmpbuf;
strm.avail_out = (uInt) decompressed_length;
strm.next_out = decompressed;
do {
dr = inflate(&strm, Z_FINISH);
if (dr == Z_STREAM_ERROR) {
xfree(decmpbuf);
printf("Compression Read Error\n");
goto rer;
}
strm.avail_out = pktlen - strm.total_out;
strm.next_out = decmpbuf + strm.total_out;
strm.avail_out = (uInt) (pktlen - strm.total_out);
strm.next_out = decompressed + strm.total_out;
} while (strm.avail_in > 0 || strm.total_out < pktlen);
inflateEnd(&strm);
pktbuf = decmpbuf;
pktlen = dl;
tf = 1;
pktbuf = decompressed;
pktlen = decompressed_length;
}
}
if (pktbuf == NULL) return 0;
unsigned char* pbuf = (unsigned char*) pktbuf;
size_t ps = pktlen;
size_t ps = (size_t) pktlen;
int32_t id = 0;
size_t t = readVarInt(&id, pbuf, ps);
size_t t = (size_t) readVarInt(&id, pbuf, ps);
pbuf += t;
ps -= t;
packet->id = id;
int rx = 0;
if (conn->state == STATE_HANDSHAKE) {
if (conn->protocol_state == STATE_HANDSHAKE) {
if (id == PKT_HANDSHAKE_SERVER_HANDSHAKE) {
//protocol_version
rx = readVarInt(&packet->data.handshake_server.handshake.protocol_version, pbuf, ps);
ADRX
//server_address
rx = readString(&packet->data.handshake_server.handshake.server_address, pbuf, ps);
rx = readString(packet->pool, &packet->data.handshake_server.handshake.server_address, pbuf, ps);
ADRX
//server_port
CPS(2)
@ -100,14 +97,14 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
rx = readVarInt(&packet->data.handshake_server.handshake.next_state, pbuf, ps);
ADRX
}
} else if (conn->state == STATE_PLAY) {
} else if (conn->protocol_state == STATE_PLAY) {
if (id == PKT_PLAY_SERVER_TELEPORTCONFIRM) {
//teleport_id
rx = readVarInt(&packet->data.play_server.teleportconfirm.teleport_id, pbuf, ps);
ADRX
} else if (id == PKT_PLAY_SERVER_TABCOMPLETE) {
//text
rx = readString(&packet->data.play_server.tabcomplete.text, pbuf, ps);
rx = readString(packet->pool, &packet->data.play_server.tabcomplete.text, pbuf, ps);
ADRX
//assume_command
CPS(1)
@ -125,7 +122,7 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
}
} else if (id == PKT_PLAY_SERVER_CHATMESSAGE) {
//message
rx = readString(&packet->data.play_server.chatmessage.message, pbuf, ps);
rx = readString(packet->pool, &packet->data.play_server.chatmessage.message, pbuf, ps);
ADRX
} else if (id == PKT_PLAY_SERVER_CLIENTSTATUS) {
//action_id
@ -133,7 +130,7 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
ADRX
} else if (id == PKT_PLAY_SERVER_CLIENTSETTINGS) {
//locale
rx = readString(&packet->data.play_server.clientsettings.locale, pbuf, ps);
rx = readString(packet->pool, &packet->data.play_server.clientsettings.locale, pbuf, ps);
ADRX
//view_distance
CPS(1)
@ -199,7 +196,7 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
rx = readVarInt(&packet->data.play_server.clickwindow.mode, pbuf, ps);
ADRX
//clicked_item
rx = readSlot(&packet->data.play_server.clickwindow.clicked_item, pbuf, ps);
rx = readSlot(packet->pool, &packet->data.play_server.clickwindow.clicked_item, pbuf, ps);
ADRX
} else if (id == PKT_PLAY_SERVER_CLOSEWINDOW) {
//window_id
@ -208,11 +205,11 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
ADX(1)
} else if (id == PKT_PLAY_SERVER_PLUGINMESSAGE) {
//channel
rx = readString(&packet->data.play_server.pluginmessage.channel, pbuf, ps);
rx = readString(packet->pool, &packet->data.play_server.pluginmessage.channel, pbuf, ps);
ADRX
//data
CPS(ps)
packet->data.play_server.pluginmessage.data = xmalloc(ps);
packet->data.play_server.pluginmessage.data = pmalloc(packet->pool, ps);
memcpy(packet->data.play_server.pluginmessage.data, pbuf, ps);
ADX(ps)
} else if (id == PKT_PLAY_SERVER_USEENTITY) {
@ -424,7 +421,7 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
swapEndian(&packet->data.play_server.creativeinventoryaction.slot, 2);
ADX(2)
//clicked_item
rx = readSlot(&packet->data.play_server.creativeinventoryaction.clicked_item, pbuf, ps);
rx = readSlot(packet->pool, &packet->data.play_server.creativeinventoryaction.clicked_item, pbuf, ps);
ADRX
} else if (id == PKT_PLAY_SERVER_UPDATESIGN) {
//location
@ -433,16 +430,16 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
swapEndian(&packet->data.play_server.updatesign.location, 8);
ADX(8)
//line_1
rx = readString(&packet->data.play_server.updatesign.line_1, pbuf, ps);
rx = readString(packet->pool, &packet->data.play_server.updatesign.line_1, pbuf, ps);
ADRX
//line_2
rx = readString(&packet->data.play_server.updatesign.line_2, pbuf, ps);
rx = readString(packet->pool, &packet->data.play_server.updatesign.line_2, pbuf, ps);
ADRX
//line_3
rx = readString(&packet->data.play_server.updatesign.line_3, pbuf, ps);
rx = readString(packet->pool, &packet->data.play_server.updatesign.line_3, pbuf, ps);
ADRX
//line_4
rx = readString(&packet->data.play_server.updatesign.line_4, pbuf, ps);
rx = readString(packet->pool, &packet->data.play_server.updatesign.line_4, pbuf, ps);
ADRX
} else if (id == PKT_PLAY_SERVER_ANIMATION) {
//hand
@ -507,7 +504,7 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
rx = readVarInt(&packet->data.play_server.useitem.hand, pbuf, ps);
ADRX
}
} else if (conn->state == STATE_STATUS) {
} else if (conn->protocol_state == STATE_STATUS) {
if (id == PKT_STATUS_SERVER_REQUEST) {
} else if (id == PKT_STATUS_SERVER_PING) {
@ -517,10 +514,10 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
swapEndian(&packet->data.status_server.ping.payload, 8);
ADX(8)
}
} else if (conn->state == STATE_LOGIN) {
} else if (conn->protocol_state == STATE_LOGIN) {
if (id == PKT_LOGIN_SERVER_LOGINSTART) {
//name
rx = readString(&packet->data.login_server.loginstart.name, pbuf, ps);
rx = readString(packet->pool, &packet->data.login_server.loginstart.name, pbuf, ps);
ADRX
} else if (id == PKT_LOGIN_SERVER_ENCRYPTIONRESPONSE) {
//shared_secret_length
@ -528,43 +525,45 @@ ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct
ADRX
//shared_secret
CPS(packet->data.login_server.encryptionresponse.shared_secret_length)
packet->data.login_server.encryptionresponse.shared_secret = xmalloc(packet->data.login_server.encryptionresponse.shared_secret_length);
memcpy(packet->data.login_server.encryptionresponse.shared_secret, pbuf, packet->data.login_server.encryptionresponse.shared_secret_length);
packet->data.login_server.encryptionresponse.shared_secret = pmalloc(packet->pool,
(size_t) packet->data.login_server.encryptionresponse.shared_secret_length);
memcpy(packet->data.login_server.encryptionresponse.shared_secret, pbuf,
(size_t) packet->data.login_server.encryptionresponse.shared_secret_length);
ADX(packet->data.login_server.encryptionresponse.shared_secret_length)
//verify_token_length
rx = readVarInt(&packet->data.login_server.encryptionresponse.verify_token_length, pbuf, ps);
rx = readVarInt((int32_t*) &packet->data.login_server.encryptionresponse.verify_token_length, pbuf, ps);
ADRX
//verify_token
CPS(packet->data.login_server.encryptionresponse.verify_token_length)
packet->data.login_server.encryptionresponse.verify_token = xmalloc(packet->data.login_server.encryptionresponse.verify_token_length);
packet->data.login_server.encryptionresponse.verify_token = pmalloc(packet->pool, packet->data.login_server.encryptionresponse.verify_token_length);
memcpy(packet->data.login_server.encryptionresponse.verify_token, pbuf, packet->data.login_server.encryptionresponse.verify_token_length);
ADX(packet->data.login_server.encryptionresponse.verify_token_length)
}
}
goto rx;
rer: ;
if (tf) xfree(pktbuf);
pfree(packet->pool);
return -1;
rx: ;
if (tf) xfree(pktbuf);
pfree(packet->pool);
return buflen;
}
ssize_t writePacket(struct conn* conn, struct packet* packet) {
if (conn->state == STATE_PLAY && packet->id == PKT_PLAY_CLIENT_CHUNKDATA) {
ssize_t writePacket(struct connection* conn, struct packet* packet) {
if (conn->protocol_state == STATE_PLAY && packet->id == PKT_PLAY_CLIENT_CHUNKDATA) {
if (!isChunkLoaded(conn->player->world, packet->data.play_client.chunkdata.cx, packet->data.play_client.chunkdata.cz)) return 0;
}
unsigned char* pktbuf = xmalloc(1034);
unsigned char* pktbuf = pmalloc(packet->pool, 522);
pktbuf += 10;
size_t ps = 1024;
size_t ps = 512;
size_t pi = 0;
size_t slb = 0;
int32_t id = packet->id;
ENS(4)
pi += writeVarInt(id, pktbuf + pi);
if (conn->state == STATE_HANDSHAKE) {
if (conn->protocol_state == STATE_HANDSHAKE) {
} else if (conn->state == STATE_PLAY) {
} else if (conn->protocol_state == STATE_PLAY) {
//printf("write %i\n", id);
if (id == PKT_PLAY_CLIENT_SPAWNOBJECT) {
//entity_id
@ -826,7 +825,7 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
pi += 1;
//nbt_data
ENS(512)
pi += writeNBT(packet->data.play_client.updateblockentity.nbt_data, pktbuf + pi, ps - pi);
pi += nbt_write(packet->data.play_client.updateblockentity.nbt_data, pktbuf + pi, ps - pi);
} else if (id == PKT_PLAY_CLIENT_BLOCKACTION) {
//location
ENS(8)
@ -935,7 +934,7 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
memcpy(pktbuf + pi, &packet->data.play_client.openwindow.number_of_slots, 1);
pi += 1;
//entity_id
if (streq(packet->data.play_client.openwindow.window_type, "EntityHorse")) {
if (str_eq(packet->data.play_client.openwindow.window_type, "EntityHorse")) {
ENS(4)
memcpy(pktbuf + pi, &packet->data.play_client.openwindow.entity_id, 4);
swapEndian(pktbuf + pi, 4);
@ -1076,7 +1075,8 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
pi += 4;
//records
ENS(packet->data.play_client.explosion.record_count * 3)
memcpy(pktbuf + pi, packet->data.play_client.explosion.records, packet->data.play_client.explosion.record_count * 3);
memcpy(pktbuf + pi, packet->data.play_client.explosion.records,
(size_t) (packet->data.play_client.explosion.record_count * 3));
pi += packet->data.play_client.explosion.record_count * 3;
//player_motion_x
ENS(4)
@ -1161,7 +1161,8 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
memcpy(pktbuf + pi, &bpb, 1);
pi += 1;
ENS(4)
pi += writeVarInt(bpb < 9 ? packet->data.play_client.chunkdata.data->sections[ymj]->palette_count : 0, pktbuf + pi);
pi += writeVarInt(
(int32_t) (bpb < 9 ? packet->data.play_client.chunkdata.data->sections[ymj]->palette_count : 0), pktbuf + pi);
for (int i = 0; i < packet->data.play_client.chunkdata.data->sections[ymj]->palette_count; i++) {
ENS(4)
pi += writeVarInt(packet->data.play_client.chunkdata.data->sections[ymj]->palette[i], pktbuf + pi);
@ -1198,7 +1199,7 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
//block_entities
for (int32_t i = 0; i < packet->data.play_client.chunkdata.number_of_block_entities; i++) {
ENS(512)
pi += writeNBT(packet->data.play_client.chunkdata.block_entities[i], pktbuf + pi, ps - pi);
pi += nbt_write(packet->data.play_client.chunkdata.block_entities[i], pktbuf + pi, ps - pi);
}
} else if (id == PKT_PLAY_CLIENT_EFFECT) {
//effect_id
@ -1893,7 +1894,7 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
memcpy(pktbuf + pi, &packet->data.play_client.entityeffect.flags, 1);
pi += 1;
}
} else if (conn->state == STATE_STATUS) {
} else if (conn->protocol_state == STATE_STATUS) {
if (id == PKT_STATUS_CLIENT_RESPONSE) {
//json_response
slb = strlen(packet->data.status_client.response.json_response) + 4;
@ -1906,7 +1907,7 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
swapEndian(pktbuf + pi, 8);
pi += 8;
}
} else if (conn->state == STATE_LOGIN) {
} else if (conn->protocol_state == STATE_LOGIN) {
if (id == PKT_LOGIN_CLIENT_DISCONNECT) {
//reason
slb = strlen(packet->data.login_client.disconnect.reason) + 4;
@ -1922,14 +1923,16 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
pi += writeVarInt(packet->data.login_client.encryptionrequest.public_key_length, pktbuf + pi);
//public_key
ENS(packet->data.login_client.encryptionrequest.public_key_length)
memcpy(pktbuf + pi, packet->data.login_client.encryptionrequest.public_key, packet->data.login_client.encryptionrequest.public_key_length);
memcpy(pktbuf + pi, packet->data.login_client.encryptionrequest.public_key,
(size_t) packet->data.login_client.encryptionrequest.public_key_length);
pi += packet->data.login_client.encryptionrequest.public_key_length;
//verify_token_length
ENS(4)
pi += writeVarInt(packet->data.login_client.encryptionrequest.verify_token_length, pktbuf + pi);
//verify_token
ENS(packet->data.login_client.encryptionrequest.verify_token_length)
memcpy(pktbuf + pi, packet->data.login_client.encryptionrequest.verify_token, packet->data.login_client.encryptionrequest.verify_token_length);
memcpy(pktbuf + pi, packet->data.login_client.encryptionrequest.verify_token,
(size_t) packet->data.login_client.encryptionrequest.verify_token_length);
pi += packet->data.login_client.encryptionrequest.verify_token_length;
} else if (id == PKT_LOGIN_CLIENT_LOGINSUCCESS) {
//uuid
@ -1949,366 +1952,70 @@ ssize_t writePacket(struct conn* conn, struct packet* packet) {
int fpll = getVarIntSize(pi);
void* wrt = NULL;
size_t wrt_s = 0;
int frp = 0;
unsigned char prep[10];
uint8_t preps = 0;
if (conn->comp >= 0 && (pi + fpll > conn->comp + 1) && (pi + fpll) <= 2097152) {
frp = 1;
if (conn->compression_state >= 0 && (pi + fpll > conn->compression_state + 1) && (pi + fpll) <= 2097152) {
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int dr = 0;
if ((dr = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY)) != Z_OK) { // TODO: configurable level?
return -1;
goto rret;
}
strm.avail_in = pi;
strm.avail_in = (uInt) pi;
strm.next_in = pktbuf;
size_t cc = pi + 32;
void* cdata = xmalloc(cc + 10);
void* cdata = pmalloc(packet->pool, cc + 10);
size_t ts = 0;
strm.avail_out = cc - ts;
strm.avail_out = (uInt) (cc - ts);
strm.next_out = cdata + ts;
do {
dr = deflate(&strm, Z_FINISH);
ts = strm.total_out;
if (ts >= cc) {
cc = ts + 1024;
cdata = xrealloc(cdata - 10, cc + 10) + 10;
cc *= 2;
cdata = prealloc(packet->pool, cdata - 10, cc + 10) + 10;
}
if (dr == Z_STREAM_ERROR) {
xfree(cdata);
return -1;
goto rret;
}
strm.avail_out = cc - ts;
strm.avail_out = (uInt) (cc - ts);
strm.next_out = cdata + ts;
} while (strm.avail_out == 0);
deflateEnd(&strm);
preps += writeVarInt(ts + getVarIntSize(pi), prep + preps);
preps += writeVarInt(pi, prep + preps);
preps += writeVarInt((int32_t) (ts + getVarIntSize((int32_t) pi)), prep + preps);
preps += writeVarInt((int32_t) pi, prep + preps);
wrt = cdata;
wrt_s = ts;
} else if (conn->comp >= 0) {
preps += writeVarInt(pi + getVarIntSize(0), prep + preps);
} else if (conn->compression_state >= 0) {
preps += writeVarInt((int32_t) (pi + getVarIntSize(0)), prep + preps);
preps += writeVarInt(0, prep + preps);
wrt = pktbuf;
wrt_s = pi;
} else {
preps += writeVarInt(pi, prep + preps);
preps += writeVarInt((int32_t) pi, prep + preps);
wrt = pktbuf;
wrt_s = pi;
}
if (preps >= 10) goto rret;
void* xfer_address = wrt - 10;
// ^ explode
wrt -= preps; // preallocated!
memcpy(wrt, prep, preps);
wrt_s += preps;
if (conn->aes_ctx_enc != NULL) {
int csl = wrt_s + 32; // 16 extra just in case
void* edata = xmalloc(csl);
if (EVP_EncryptUpdate(conn->aes_ctx_enc, edata, &csl, wrt, wrt_s) != 1) {
xfree(edata);
wrt_s = -1;
size_t encrypted_length = wrt_s + 32; // 16 extra just in case
void* encrypted = pmalloc(packet->pool, encrypted_length);
if (EVP_EncryptUpdate(conn->aes_ctx_enc, encrypted, &encrypted_length, wrt, (int) wrt_s) != 1) {
wrt_s = (size_t) -1;
goto rret;
}
xfree(wrt + preps - 10);
if (!frp) pktbuf = NULL;
wrt = edata;
wrt_s = csl;
//
/*if (EVP_DecryptInit_ex(conn->aes_ctx_dec, EVP_aes_128_cfb8(), NULL, conn->sharedSecret, conn->sharedSecret) != 1) return -1;
csl = wrt_s + 32; // 16 extra just in case
edata = xcalloc(csl);
if (EVP_DecryptUpdate(conn->aes_ctx_dec, edata, &csl, wrt, wrt_s) != 1) {
xfree(edata);
wrt_s = -1;
goto rret;
}
csl2 = 0;
if (EVP_DecryptFinal_ex(conn->aes_ctx_dec, edata + csl, &csl2) != 1) {
xfree(edata);
wrt_s = -1;
goto rret;
}
csl += csl2;
if (csl != owrts) {
printf("length mismatch! %i != %i\n", csl, owrts);
} else {
printf("original data: ");
for (int i = 0; i < owrts; i++) {
printf("%02X", ((uint8_t*) owrt)[i]);
}
printf("\nshared secret: ");
for (int i = 0; i < 16; i++) {
printf("%02X", ((uint8_t*) conn->sharedSecret)[i]);
}
printf("\nenc data: ");
for (int i = 0; i < wrt_s; i++) {
printf("%02X", ((uint8_t*) wrt)[i]);
}
printf("\ndec/enc data: ");
for (int i = 0; i < csl; i++) {
printf("%02X", ((uint8_t*) edata)[i]);
}
printf("\n%s\n", memeq(owrt, owrts, edata, csl) ? "equal!" : "not equal!");
}
xfree(owrt);
xfree(edata);*/
}
if (conn->writeBuffer == NULL) {
conn->writeBuffer = xmalloc(wrt_s * 10);
memcpy(conn->writeBuffer, wrt, wrt_s);
conn->writeBuffer_size = wrt_s;
conn->writeBuffer_capacity = wrt_s * 10;
} else {
if ((conn->writeBuffer_capacity - conn->writeBuffer_size) <= wrt_s) {
conn->writeBuffer_capacity += wrt_s * 10;
conn->writeBuffer = xrealloc(conn->writeBuffer, conn->writeBuffer_capacity);
}
memcpy(conn->writeBuffer + conn->writeBuffer_size, wrt, wrt_s);
conn->writeBuffer_size += wrt_s;
xfer_address = wrt = encrypted;
wrt_s = encrypted_length;
}
pxfer(packet->pool, conn->managed_conn->write_buffer.pool, xfer_address);
buffer_push_partial(&conn->managed_conn->write_buffer, xfer_address, wrt, wrt_s);
rret: ;
if (frp) xfree(wrt + preps - 10);
if (pktbuf != NULL) xfree(pktbuf - 10);
return wrt_s;
}
void freePacket(int state, int dir, struct packet* packet) {
if (state == STATE_HANDSHAKE) {
if (dir == 1) {
}
if (dir == 0) {
if (packet->id == PKT_HANDSHAKE_SERVER_HANDSHAKE) {
if (packet->data.handshake_server.handshake.server_address != NULL) xfree(packet->data.handshake_server.handshake.server_address);
}
}
} else if (state == STATE_PLAY) {
if (dir == 1) {
if (packet->id == PKT_PLAY_CLIENT_SPAWNOBJECT) {
} else if (packet->id == PKT_PLAY_CLIENT_SPAWNEXPERIENCEORB) {
} else if (packet->id == PKT_PLAY_CLIENT_SPAWNGLOBALENTITY) {
} else if (packet->id == PKT_PLAY_CLIENT_SPAWNMOB) {
if (packet->data.play_client.spawnmob.metadata.metadata != NULL) xfree(packet->data.play_client.spawnmob.metadata.metadata);
} else if (packet->id == PKT_PLAY_CLIENT_SPAWNPAINTING) {
if (packet->data.play_client.spawnpainting.title != NULL) xfree(packet->data.play_client.spawnpainting.title);
} else if (packet->id == PKT_PLAY_CLIENT_SPAWNPLAYER) {
if (packet->data.play_client.spawnplayer.metadata.metadata != NULL) xfree(packet->data.play_client.spawnplayer.metadata.metadata);
} else if (packet->id == PKT_PLAY_CLIENT_ANIMATION) {
} else if (packet->id == PKT_PLAY_CLIENT_STATISTICS) {
//TODO: Manual Implementation
} else if (packet->id == PKT_PLAY_CLIENT_BLOCKBREAKANIMATION) {
} else if (packet->id == PKT_PLAY_CLIENT_UPDATEBLOCKENTITY) {
if (packet->data.play_client.updateblockentity.nbt_data != NULL) freeNBT(packet->data.play_client.updateblockentity.nbt_data);
} else if (packet->id == PKT_PLAY_CLIENT_BLOCKACTION) {
} else if (packet->id == PKT_PLAY_CLIENT_BLOCKCHANGE) {
} else if (packet->id == PKT_PLAY_CLIENT_BOSSBAR) {
//TODO: Manual Implementation
} else if (packet->id == PKT_PLAY_CLIENT_SERVERDIFFICULTY) {
} else if (packet->id == PKT_PLAY_CLIENT_TABCOMPLETE) {
if (packet->data.play_client.tabcomplete.matches != NULL) xfree(packet->data.play_client.tabcomplete.matches);
} else if (packet->id == PKT_PLAY_CLIENT_CHATMESSAGE) {
if (packet->data.play_client.chatmessage.json_data != NULL) xfree(packet->data.play_client.chatmessage.json_data);
} else if (packet->id == PKT_PLAY_CLIENT_MULTIBLOCKCHANGE) {
//TODO: Manual Implementation
} else if (packet->id == PKT_PLAY_CLIENT_CONFIRMTRANSACTION) {
} else if (packet->id == PKT_PLAY_CLIENT_CLOSEWINDOW) {
} else if (packet->id == PKT_PLAY_CLIENT_OPENWINDOW) {
if (packet->data.play_client.openwindow.window_type != NULL) xfree(packet->data.play_client.openwindow.window_type);
if (packet->data.play_client.openwindow.window_title != NULL) xfree(packet->data.play_client.openwindow.window_title);
} else if (packet->id == PKT_PLAY_CLIENT_WINDOWITEMS) {
if (packet->data.play_client.windowitems.slot_data != NULL) {
for (size_t i = 0; i < packet->data.play_client.windowitems.count; i++) {
if (packet->data.play_client.windowitems.slot_data[i].nbt != NULL) freeNBT(packet->data.play_client.windowitems.slot_data[i].nbt);
}
xfree(packet->data.play_client.windowitems.slot_data);
}
} else if (packet->id == PKT_PLAY_CLIENT_WINDOWPROPERTY) {
} else if (packet->id == PKT_PLAY_CLIENT_SETSLOT) {
if (packet->data.play_client.setslot.slot_data.nbt != NULL) freeNBT(packet->data.play_client.setslot.slot_data.nbt);
} else if (packet->id == PKT_PLAY_CLIENT_SETCOOLDOWN) {
} else if (packet->id == PKT_PLAY_CLIENT_PLUGINMESSAGE) {
if (packet->data.play_client.pluginmessage.channel != NULL) xfree(packet->data.play_client.pluginmessage.channel);
} else if (packet->id == PKT_PLAY_CLIENT_NAMEDSOUNDEFFECT) {
if (packet->data.play_client.namedsoundeffect.sound_name != NULL) xfree(packet->data.play_client.namedsoundeffect.sound_name);
} else if (packet->id == PKT_PLAY_CLIENT_DISCONNECT) {
if (packet->data.play_client.disconnect.reason != NULL) xfree(packet->data.play_client.disconnect.reason);
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYSTATUS) {
} else if (packet->id == PKT_PLAY_CLIENT_EXPLOSION) {
} else if (packet->id == PKT_PLAY_CLIENT_UNLOADCHUNK) {
} else if (packet->id == PKT_PLAY_CLIENT_CHANGEGAMESTATE) {
} else if (packet->id == PKT_PLAY_CLIENT_KEEPALIVE) {
} else if (packet->id == PKT_PLAY_CLIENT_CHUNKDATA) {
//TODO: Manual implementation.
if (packet->data.play_client.chunkdata.block_entities != NULL) {
for (size_t i = 0; i < packet->data.play_client.chunkdata.number_of_block_entities; i++) {
if (packet->data.play_client.chunkdata.block_entities[i] != NULL) freeNBT(packet->data.play_client.chunkdata.block_entities[i]);
}
xfree(packet->data.play_client.chunkdata.block_entities);
}
} else if (packet->id == PKT_PLAY_CLIENT_EFFECT) {
} else if (packet->id == PKT_PLAY_CLIENT_PARTICLE) {
} else if (packet->id == PKT_PLAY_CLIENT_JOINGAME) {
if (packet->data.play_client.joingame.level_type != NULL) xfree(packet->data.play_client.joingame.level_type);
} else if (packet->id == PKT_PLAY_CLIENT_MAP) {
//TODO: Manual Implementation
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYRELATIVEMOVE) {
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYLOOKANDRELATIVEMOVE) {
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYLOOK) {
} else if (packet->id == PKT_PLAY_CLIENT_ENTITY) {
} else if (packet->id == PKT_PLAY_CLIENT_VEHICLEMOVE) {
} else if (packet->id == PKT_PLAY_CLIENT_OPENSIGNEDITOR) {
} else if (packet->id == PKT_PLAY_CLIENT_PLAYERABILITIES) {
} else if (packet->id == PKT_PLAY_CLIENT_COMBATEVENT) {
//TODO: Manual Implementation
} else if (packet->id == PKT_PLAY_CLIENT_PLAYERLISTITEM) {
if (packet->data.play_client.playerlistitem.players != NULL) {
for (int32_t i = 0; i < packet->data.play_client.playerlistitem.number_of_players; i++) {
if (packet->data.play_client.playerlistitem.action_id == 0) {
xfree(packet->data.play_client.playerlistitem.players[i].action.addplayer.name);
xfree(packet->data.play_client.playerlistitem.players[i].action.addplayer.display_name);
if (packet->data.play_client.playerlistitem.players[i].action.addplayer.properties != NULL) {
for (int32_t x = 0; x < packet->data.play_client.playerlistitem.players[i].action.addplayer.number_of_properties; x++) {
xfree(packet->data.play_client.playerlistitem.players[i].action.addplayer.properties[x].name);
xfree(packet->data.play_client.playerlistitem.players[i].action.addplayer.properties[x].value);
xfree(packet->data.play_client.playerlistitem.players[i].action.addplayer.properties[x].signature);
}
xfree(packet->data.play_client.playerlistitem.players[i].action.addplayer.properties);
}
} else if (packet->data.play_client.playerlistitem.action_id == 3) {
xfree(packet->data.play_client.playerlistitem.players[i].action.addplayer.display_name);
}
}
xfree(packet->data.play_client.playerlistitem.players);
}
} else if (packet->id == PKT_PLAY_CLIENT_PLAYERPOSITIONANDLOOK) {
} else if (packet->id == PKT_PLAY_CLIENT_USEBED) {
} else if (packet->id == PKT_PLAY_CLIENT_DESTROYENTITIES) {
if (packet->data.play_client.destroyentities.entity_ids != NULL) xfree(packet->data.play_client.destroyentities.entity_ids);
} else if (packet->id == PKT_PLAY_CLIENT_REMOVEENTITYEFFECT) {
} else if (packet->id == PKT_PLAY_CLIENT_RESOURCEPACKSEND) {
if (packet->data.play_client.resourcepacksend.url != NULL) xfree(packet->data.play_client.resourcepacksend.url);
if (packet->data.play_client.resourcepacksend.hash != NULL) xfree(packet->data.play_client.resourcepacksend.hash);
} else if (packet->id == PKT_PLAY_CLIENT_RESPAWN) {
if (packet->data.play_client.respawn.level_type != NULL) xfree(packet->data.play_client.respawn.level_type);
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYHEADLOOK) {
} else if (packet->id == PKT_PLAY_CLIENT_WORLDBORDER) {
//TODO: Manual Implementation
} else if (packet->id == PKT_PLAY_CLIENT_CAMERA) {
} else if (packet->id == PKT_PLAY_CLIENT_HELDITEMCHANGE) {
} else if (packet->id == PKT_PLAY_CLIENT_DISPLAYSCOREBOARD) {
if (packet->data.play_client.displayscoreboard.score_name != NULL) xfree(packet->data.play_client.displayscoreboard.score_name);
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYMETADATA) {
if (packet->data.play_client.entitymetadata.metadata.metadata != NULL) xfree(packet->data.play_client.entitymetadata.metadata.metadata);
} else if (packet->id == PKT_PLAY_CLIENT_ATTACHENTITY) {
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYVELOCITY) {
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYEQUIPMENT) {
if (packet->data.play_client.entityequipment.item.nbt != NULL) freeNBT(packet->data.play_client.entityequipment.item.nbt);
} else if (packet->id == PKT_PLAY_CLIENT_SETEXPERIENCE) {
} else if (packet->id == PKT_PLAY_CLIENT_UPDATEHEALTH) {
} else if (packet->id == PKT_PLAY_CLIENT_SCOREBOARDOBJECTIVE) {
if (packet->data.play_client.scoreboardobjective.objective_name != NULL) xfree(packet->data.play_client.scoreboardobjective.objective_name);
if (packet->data.play_client.scoreboardobjective.objective_value != NULL) xfree(packet->data.play_client.scoreboardobjective.objective_value);
if (packet->data.play_client.scoreboardobjective.type != NULL) xfree(packet->data.play_client.scoreboardobjective.type);
} else if (packet->id == PKT_PLAY_CLIENT_SETPASSENGERS) {
} else if (packet->id == PKT_PLAY_CLIENT_TEAMS) {
//TODO: Manual Implementation
} else if (packet->id == PKT_PLAY_CLIENT_UPDATESCORE) {
if (packet->data.play_client.updatescore.score_name != NULL) xfree(packet->data.play_client.updatescore.score_name);
if (packet->data.play_client.updatescore.objective_name != NULL) xfree(packet->data.play_client.updatescore.objective_name);
} else if (packet->id == PKT_PLAY_CLIENT_SPAWNPOSITION) {
} else if (packet->id == PKT_PLAY_CLIENT_TIMEUPDATE) {
} else if (packet->id == PKT_PLAY_CLIENT_TITLE) {
//TODO: Manual Implementation
} else if (packet->id == PKT_PLAY_CLIENT_SOUNDEFFECT) {
} else if (packet->id == PKT_PLAY_CLIENT_PLAYERLISTHEADERANDFOOTER) {
if (packet->data.play_client.playerlistheaderandfooter.header != NULL) xfree(packet->data.play_client.playerlistheaderandfooter.header);
if (packet->data.play_client.playerlistheaderandfooter.footer != NULL) xfree(packet->data.play_client.playerlistheaderandfooter.footer);
} else if (packet->id == PKT_PLAY_CLIENT_COLLECTITEM) {
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYTELEPORT) {
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYPROPERTIES) {
for (int32_t i = 0; i < packet->data.play_client.entityproperties.number_of_properties; i++) {
xfree(packet->data.play_client.entityproperties.properties[i].key);
xfree(packet->data.play_client.entityproperties.properties[i].modifiers);
}
xfree(packet->data.play_client.entityproperties.properties);
} else if (packet->id == PKT_PLAY_CLIENT_ENTITYEFFECT) {
}
}
if (dir == 0) {
if (packet->id == PKT_PLAY_SERVER_TELEPORTCONFIRM) {
} else if (packet->id == PKT_PLAY_SERVER_TABCOMPLETE) {
if (packet->data.play_server.tabcomplete.text != NULL) xfree(packet->data.play_server.tabcomplete.text);
} else if (packet->id == PKT_PLAY_SERVER_CHATMESSAGE) {
if (packet->data.play_server.chatmessage.message != NULL) xfree(packet->data.play_server.chatmessage.message);
} else if (packet->id == PKT_PLAY_SERVER_CLIENTSTATUS) {
} else if (packet->id == PKT_PLAY_SERVER_CLIENTSETTINGS) {
if (packet->data.play_server.clientsettings.locale != NULL) xfree(packet->data.play_server.clientsettings.locale);
} else if (packet->id == PKT_PLAY_SERVER_CONFIRMTRANSACTION) {
} else if (packet->id == PKT_PLAY_SERVER_ENCHANTITEM) {
} else if (packet->id == PKT_PLAY_SERVER_CLICKWINDOW) {
if (packet->data.play_server.clickwindow.clicked_item.nbt != NULL) freeNBT(packet->data.play_server.clickwindow.clicked_item.nbt);
} else if (packet->id == PKT_PLAY_SERVER_CLOSEWINDOW) {
} else if (packet->id == PKT_PLAY_SERVER_PLUGINMESSAGE) {
if (packet->data.play_server.pluginmessage.channel != NULL) xfree(packet->data.play_server.pluginmessage.channel);
} else if (packet->id == PKT_PLAY_SERVER_USEENTITY) {
} else if (packet->id == PKT_PLAY_SERVER_KEEPALIVE) {
} else if (packet->id == PKT_PLAY_SERVER_PLAYERPOSITION) {
} else if (packet->id == PKT_PLAY_SERVER_PLAYERPOSITIONANDLOOK) {
} else if (packet->id == PKT_PLAY_SERVER_PLAYERLOOK) {
} else if (packet->id == PKT_PLAY_SERVER_PLAYER) {
} else if (packet->id == PKT_PLAY_SERVER_VEHICLEMOVE) {
} else if (packet->id == PKT_PLAY_SERVER_STEERBOAT) {
} else if (packet->id == PKT_PLAY_SERVER_PLAYERABILITIES) {
} else if (packet->id == PKT_PLAY_SERVER_PLAYERDIGGING) {
} else if (packet->id == PKT_PLAY_SERVER_ENTITYACTION) {
} else if (packet->id == PKT_PLAY_SERVER_STEERVEHICLE) {
} else if (packet->id == PKT_PLAY_SERVER_RESOURCEPACKSTATUS) {
} else if (packet->id == PKT_PLAY_SERVER_HELDITEMCHANGE) {
} else if (packet->id == PKT_PLAY_SERVER_CREATIVEINVENTORYACTION) {
if (packet->data.play_server.creativeinventoryaction.clicked_item.nbt != NULL) freeNBT(packet->data.play_server.creativeinventoryaction.clicked_item.nbt);
} else if (packet->id == PKT_PLAY_SERVER_UPDATESIGN) {
if (packet->data.play_server.updatesign.line_1 != NULL) xfree(packet->data.play_server.updatesign.line_1);
if (packet->data.play_server.updatesign.line_2 != NULL) xfree(packet->data.play_server.updatesign.line_2);
if (packet->data.play_server.updatesign.line_3 != NULL) xfree(packet->data.play_server.updatesign.line_3);
if (packet->data.play_server.updatesign.line_4 != NULL) xfree(packet->data.play_server.updatesign.line_4);
} else if (packet->id == PKT_PLAY_SERVER_ANIMATION) {
} else if (packet->id == PKT_PLAY_SERVER_SPECTATE) {
} else if (packet->id == PKT_PLAY_SERVER_PLAYERBLOCKPLACEMENT) {
} else if (packet->id == PKT_PLAY_SERVER_USEITEM) {
}
}
} else if (state == STATE_STATUS) {
if (dir == 1) {
if (packet->id == PKT_STATUS_CLIENT_RESPONSE) {
if (packet->data.status_client.response.json_response != NULL) xfree(packet->data.status_client.response.json_response);
} else if (packet->id == PKT_STATUS_CLIENT_PONG) {
}
}
if (dir == 0) {
if (packet->id == PKT_STATUS_SERVER_REQUEST) {
//TODO: Manual Implementation
} else if (packet->id == PKT_STATUS_SERVER_PING) {
}
}
} else if (state == STATE_LOGIN) {
if (dir == 1) {
if (packet->id == PKT_LOGIN_CLIENT_DISCONNECT) {
if (packet->data.login_client.disconnect.reason != NULL) xfree(packet->data.login_client.disconnect.reason);
} else if (packet->id == PKT_LOGIN_CLIENT_ENCRYPTIONREQUEST) {
if (packet->data.login_client.encryptionrequest.server_id != NULL) xfree(packet->data.login_client.encryptionrequest.server_id);
} else if (packet->id == PKT_LOGIN_CLIENT_LOGINSUCCESS) {
if (packet->data.login_client.loginsuccess.uuid != NULL) xfree(packet->data.login_client.loginsuccess.uuid);
if (packet->data.login_client.loginsuccess.username != NULL) xfree(packet->data.login_client.loginsuccess.username);
} else if (packet->id == PKT_LOGIN_CLIENT_SETCOMPRESSION) {
}
}
if (dir == 0) {
if (packet->id == PKT_LOGIN_SERVER_LOGINSTART) {
if (packet->data.login_server.loginstart.name != NULL) xfree(packet->data.login_server.loginstart.name);
} else if (packet->id == PKT_LOGIN_SERVER_ENCRYPTIONRESPONSE) {
}
}
}
}

View File

@ -1,7 +1,8 @@
#ifndef PACKET_H_
#define PACKET_H_
#include "basin/network.h"
#include <basin/connection.h>
#include <basin/network.h>
#define STATE_HANDSHAKE 0
#define STATE_PLAY 3
@ -1111,7 +1112,7 @@ struct pkt_login_server_loginstart {
struct pkt_login_server_encryptionresponse {
int32_t shared_secret_length;
uint8_t* shared_secret;
int32_t verify_token_length;
size_t verify_token_length;
uint8_t* verify_token;
};
@ -1268,13 +1269,14 @@ union pkts {
};
struct packet {
struct mempool* pool;
int32_t id;
union pkts data;
};
ssize_t readPacket(struct conn* conn, unsigned char* buf, size_t buflen, struct packet* packet);
ssize_t readPacket(struct connection* conn, unsigned char* buf, size_t buflen, struct packet* packet);
ssize_t writePacket(struct conn* conn, struct packet* packet);
ssize_t writePacket(struct connection* conn, struct packet* packet);
void freePacket(int state, int dir, struct packet* packet);

View File

@ -23,21 +23,21 @@ struct tile_entity* parseTileEntity(struct nbt_tag* tag) {
struct tile_entity* te = xmalloc(sizeof(struct tile_entity));
te->id = NULL;
struct nbt_tag* tmp = NULL;
tmp = getNBTChild(tag, "id");
tmp = nbt_get(tag, "id");
if (tmp == NULL || tmp->id != NBT_TAG_STRING) goto cer;
te->id = xstrdup(tmp->data.nbt_string, 0);
tmp = getNBTChild(tag, "x");
tmp = nbt_get(tag, "x");
if (tmp == NULL || tmp->id != NBT_TAG_INT) goto cer;
te->x = tmp->data.nbt_int;
tmp = getNBTChild(tag, "y");
tmp = nbt_get(tag, "y");
if (tmp == NULL || tmp->id != NBT_TAG_INT) goto cer;
te->y = tmp->data.nbt_int;
tmp = getNBTChild(tag, "z");
tmp = nbt_get(tag, "z");
if (tmp == NULL || tmp->id != NBT_TAG_INT) goto cer;
te->z = tmp->data.nbt_int;
te->tick = NULL;
if (streq_nocase(te->id, "minecraft:chest")) {
tmp = getNBTChild(tag, "CustomName");
tmp = nbt_get(tag, "CustomName");
te->data.chest.inv = xmalloc(sizeof(struct inventory));
newInventory(te->data.chest.inv, INVTYPE_CHEST, 2, 27);
te->data.chest.inv->te = te;
@ -47,29 +47,29 @@ struct tile_entity* parseTileEntity(struct nbt_tag* tag) {
te->data.chest.inv->title = xmalloc(tl);
snprintf(te->data.chest.inv->title, tl, "{\"text\": \"%s\"}", tmp->data.nbt_string);
}
tmp = getNBTChild(tag, "Lock");
tmp = nbt_get(tag, "Lock");
if (tmp == NULL) te->data.chest.lock = NULL;
else te->data.chest.lock = xstrdup(tmp->data.nbt_string, 0);
struct nbt_tag* items = getNBTChild(tag, "Items");
struct nbt_tag* items = nbt_get(tag, "Items");
if (items == NULL || items->id != NBT_TAG_LIST) {
} else for (int i = 0; i < items->children_count; i++) {
struct nbt_tag* nitem = items->children[i];
if (nitem == NULL || nitem->id != NBT_TAG_COMPOUND) continue;
tmp = getNBTChild(nitem, "Slot");
tmp = nbt_get(nitem, "Slot");
if (tmp == NULL || tmp->id != NBT_TAG_BYTE) continue;
uint8_t sli = tmp->data.nbt_byte;
if (sli > 26) continue;
struct slot* sl = xmalloc(sizeof(struct slot));
tmp = getNBTChild(nitem, "id");
tmp = nbt_get(nitem, "id");
if (tmp == NULL || tmp->id != NBT_TAG_STRING) continue;
sl->item = getItemFromName(tmp->data.nbt_string);
tmp = getNBTChild(nitem, "Count");
tmp = nbt_get(nitem, "Count");
if (tmp == NULL || tmp->id != NBT_TAG_BYTE) continue;
sl->itemCount = tmp->data.nbt_byte;
tmp = getNBTChild(nitem, "Damage");
tmp = nbt_get(nitem, "Damage");
if (tmp == NULL || tmp->id != NBT_TAG_SHORT) continue;
sl->damage = tmp->data.nbt_short;
tmp = getNBTChild(nitem, "tag");
tmp = nbt_get(nitem, "tag");
if (tmp == NULL || tmp->id != NBT_TAG_COMPOUND) {
sl->nbt = NULL;
} else {
@ -80,7 +80,7 @@ struct tile_entity* parseTileEntity(struct nbt_tag* tag) {
}
} else if (streq_nocase(te->id, "minecraft:furnace")) {
te->tick = tetick_furnace;
tmp = getNBTChild(tag, "CustomName");
tmp = nbt_get(tag, "CustomName");
te->data.furnace.inv = xmalloc(sizeof(struct inventory));
newInventory(te->data.furnace.inv, INVTYPE_CHEST, 2, 27);
te->data.furnace.inv->te = te;
@ -90,38 +90,38 @@ struct tile_entity* parseTileEntity(struct nbt_tag* tag) {
te->data.furnace.inv->title = xmalloc(tl);
snprintf(te->data.furnace.inv->title, tl, "{\"text\": \"%s\"}", tmp->data.nbt_string);
}
tmp = getNBTChild(tag, "Lock");
tmp = nbt_get(tag, "Lock");
if (tmp == NULL) te->data.chest.lock = NULL;
else te->data.furnace.lock = xstrdup(tmp->data.nbt_string, 0);
tmp = getNBTChild(tag, "BurnTime");
tmp = nbt_get(tag, "BurnTime");
if (tmp == NULL) te->data.furnace.burnTime = 0;
else te->data.furnace.burnTime = tmp->data.nbt_short;
tmp = getNBTChild(tag, "CookTime");
tmp = nbt_get(tag, "CookTime");
if (tmp == NULL) te->data.furnace.cookTime = 0;
else te->data.furnace.cookTime = tmp->data.nbt_short;
tmp = getNBTChild(tag, "CookTimeTotal");
tmp = nbt_get(tag, "CookTimeTotal");
if (tmp == NULL) te->data.furnace.cookTimeTotal = 0;
else te->data.furnace.cookTimeTotal = tmp->data.nbt_short;
struct nbt_tag* items = getNBTChild(tag, "Items");
struct nbt_tag* items = nbt_get(tag, "Items");
if (items == NULL || items->id != NBT_TAG_LIST) {
} else for (int i = 0; i < items->children_count; i++) {
struct nbt_tag* nitem = items->children[i];
if (nitem == NULL || nitem->id != NBT_TAG_COMPOUND) continue;
tmp = getNBTChild(nitem, "Slot");
tmp = nbt_get(nitem, "Slot");
if (tmp == NULL || tmp->id != NBT_TAG_BYTE) continue;
uint8_t sli = tmp->data.nbt_byte;
if (sli > 26) continue;
struct slot* sl = xmalloc(sizeof(struct slot));
tmp = getNBTChild(nitem, "id");
tmp = nbt_get(nitem, "id");
if (tmp == NULL || tmp->id != NBT_TAG_STRING) continue;
sl->item = getItemFromName(tmp->data.nbt_string);
tmp = getNBTChild(nitem, "Count");
tmp = nbt_get(nitem, "Count");
if (tmp == NULL || tmp->id != NBT_TAG_BYTE) continue;
sl->itemCount = tmp->data.nbt_byte;
tmp = getNBTChild(nitem, "Damage");
tmp = nbt_get(nitem, "Damage");
if (tmp == NULL || tmp->id != NBT_TAG_SHORT) continue;
sl->damage = tmp->data.nbt_short;
tmp = getNBTChild(nitem, "tag");
tmp = nbt_get(nitem, "tag");
if (tmp == NULL || tmp->id != NBT_TAG_COMPOUND) {
sl->nbt = NULL;
} else {

View File

@ -10,6 +10,7 @@
#include "packet.h"
#include <basin/network.h>
#include <basin/globals.h>
#include <basin/connection.h>
#include <basin/entity.h>
#include <basin/server.h>
#include <basin/worldmanager.h>
@ -36,6 +37,7 @@
#include <stdio.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <avuna/util.h>
void closeConn(struct work_param* param, struct conn* conn) {
close(conn->fd);
@ -216,87 +218,81 @@ int work_joinServer(struct conn* conn, char* username, char* uuids) {
return 0;
}
int handleRead(struct conn* conn, struct work_param* param, int fd) {
if (conn->disconnect) return 0;
void* abuf;
size_t asze;
if (conn->aes_ctx_dec != NULL) {
int csl = conn->readBuffer_size + 32; // 16 extra just in case
void* edata = xmalloc(csl);
if (EVP_DecryptUpdate(conn->aes_ctx_dec, edata, &csl, conn->readBuffer, conn->readBuffer_size) != 1) {
xfree(edata);
return -1;
}
if (csl == 0) return 0;
if (conn->readDecBuffer == NULL) {
conn->readDecBuffer = xmalloc(csl);
conn->readDecBuffer_size = 0;
} else {
conn->readDecBuffer = xrealloc(conn->readDecBuffer, csl + conn->readDecBuffer_size);
}
memcpy(conn->readDecBuffer + conn->readDecBuffer_size, edata, csl);
conn->readDecBuffer_size += csl;
abuf = conn->readDecBuffer;
asze = conn->readDecBuffer_size;
xfree(conn->readBuffer);
conn->readBuffer = NULL;
conn->readBuffer_size = 0;
} else {
abuf = conn->readBuffer;
asze = conn->readBuffer_size;
int connection_read(struct netmgr_connection* netmgr_conn, uint8_t* read_buf, size_t read_buf_len) {
struct connection* conn = netmgr_conn->extra;
if (conn->disconnect) {
return 1;
}
while (abuf != NULL && asze > 0) {
if (conn->aes_ctx_dec != NULL) {
int decrypted_length = (int) (read_buf_len + 32); // 16 extra just in case
void* decrypted = pmalloc(netmgr_conn->read_buffer.pool, (size_t) decrypted_length);
if (EVP_DecryptUpdate(conn->aes_ctx_dec, decrypted, &decrypted_length, read_buf, (int) read_buf_len) != 1) {
pprefree(netmgr_conn->read_buffer.pool, decrypted);
return 1;
}
if (decrypted_length == 0) return 0;
buffer_push(&netmgr_conn->read_buffer, decrypted, (size_t) decrypted_length);
pprefree(netmgr_conn->read_buffer.pool, read_buf);
} else {
buffer_push(&netmgr_conn->read_buffer, read_buf, read_buf_len);
}
while (netmgr_conn->read_buffer.size > 4) {
uint8_t peek_buf[8];
buffer_peek(&netmgr_conn->read_buffer, 5, peek_buf);
int32_t length = 0;
if (!readVarInt(&length, abuf, asze)) {
if (!readVarInt(&length, peek_buf, 5)) {
return 0;
}
int ls = getVarIntSize(length);
if (asze - ls < length) {
if (netmgr_conn->read_buffer.size - ls < length) {
return 0;
}
struct packet* inp = xmalloc(sizeof(struct packet));
ssize_t rx = readPacket(conn, abuf + ls, length, inp);
if (rx == -1) goto rete;
//printf("State = %i, ID = %i, Data = ", conn->state, inp->id);
//for (size_t i = 0; i < length + ls; i++) {
// uint8_t ch = ((uint8_t*) conn->readBuffer)[i];
// printf("%02X", ch);
//}
//printf("\n");
buffer_skip(&netmgr_conn->read_buffer, (size_t) ls);
struct mempool* packet_pool = mempool_new();
pchild(conn->pool, packet_pool);
uint8_t* packet_buf = pmalloc(packet_pool, (size_t) length);
buffer_pop(&netmgr_conn->read_buffer, (size_t) length, packet_buf);
struct packet* packet = pmalloc(packet_pool, sizeof(struct packet));
packet->pool = packet_pool;
ssize_t read_packet_length = readPacket(conn, packet_buf, (size_t) length, packet);
if (read_packet_length == -1) goto rete;
int os = conn->state;
struct packet rep;
int df = 0;
if (conn->state == STATE_HANDSHAKE && inp->id == PKT_HANDSHAKE_SERVER_HANDSHAKE) {
conn->host_ip = xstrdup(inp->data.handshake_server.handshake.server_address, 0);
conn->host_port = inp->data.handshake_server.handshake.server_port;
conn->protocolVersion = inp->data.handshake_server.handshake.protocol_version;
if ((inp->data.handshake_server.handshake.protocol_version < MC_PROTOCOL_VERSION_MIN || inp->data.handshake_server.handshake.protocol_version > MC_PROTOCOL_VERSION_MAX) && inp->data.handshake_server.handshake.next_state != STATE_STATUS) return -2;
if (inp->data.handshake_server.handshake.next_state == STATE_STATUS) {
if (conn->state == STATE_HANDSHAKE && packet->id == PKT_HANDSHAKE_SERVER_HANDSHAKE) {
conn->host_ip = xstrdup(packet->data.handshake_server.handshake.server_address, 0);
conn->host_port = packet->data.handshake_server.handshake.server_port;
conn->protocolVersion = packet->data.handshake_server.handshake.protocol_version;
if ((packet->data.handshake_server.handshake.protocol_version < MC_PROTOCOL_VERSION_MIN || packet->data.handshake_server.handshake.protocol_version > MC_PROTOCOL_VERSION_MAX) && packet->data.handshake_server.handshake.next_state != STATE_STATUS) return -2;
if (packet->data.handshake_server.handshake.next_state == STATE_STATUS) {
conn->state = STATE_STATUS;
} else if (inp->data.handshake_server.handshake.next_state == STATE_LOGIN) {
} else if (packet->data.handshake_server.handshake.next_state == STATE_LOGIN) {
conn->state = STATE_LOGIN;
} else goto rete;
} else if (conn->state == STATE_STATUS) {
if (inp->id == PKT_STATUS_SERVER_REQUEST) {
if (packet->id == PKT_STATUS_SERVER_REQUEST) {
rep.id = PKT_STATUS_CLIENT_RESPONSE;
rep.data.status_client.response.json_response = xmalloc(1000);
rep.data.status_client.response.json_response[999] = 0;
snprintf(rep.data.status_client.response.json_response, 999, "{\"version\":{\"name\":\"1.11.2\",\"protocol\":%i},\"players\":{\"max\":%i,\"online\":%i},\"description\":{\"text\":\"%s\"}}", MC_PROTOCOL_VERSION_MIN, max_players, players->entry_count, motd);
if (writePacket(conn, &rep) < 0) goto rete;
xfree(rep.data.status_client.response.json_response);
} else if (inp->id == PKT_STATUS_SERVER_PING) {
} else if (packet->id == PKT_STATUS_SERVER_PING) {
rep.id = PKT_STATUS_CLIENT_PONG;
if (writePacket(conn, &rep) < 0) goto rete;
conn->state = -1;
} else goto rete;
} else if (conn->state == STATE_LOGIN) {
if (inp->id == PKT_LOGIN_SERVER_ENCRYPTIONRESPONSE) {
if (conn->verifyToken == 0 || inp->data.login_server.encryptionresponse.shared_secret_length > 162 || inp->data.login_server.encryptionresponse.verify_token_length > 162) goto rete;
if (packet->id == PKT_LOGIN_SERVER_ENCRYPTIONRESPONSE) {
if (conn->verifyToken == 0 || packet->data.login_server.encryptionresponse.shared_secret_length > 162 || packet->data.login_server.encryptionresponse.verify_token_length > 162) goto rete;
unsigned char decSecret[162];
int secLen = RSA_private_decrypt(inp->data.login_server.encryptionresponse.shared_secret_length, inp->data.login_server.encryptionresponse.shared_secret, decSecret, public_rsa, RSA_PKCS1_PADDING);
int secLen = RSA_private_decrypt(packet->data.login_server.encryptionresponse.shared_secret_length, packet->data.login_server.encryptionresponse.shared_secret, decSecret, public_rsa, RSA_PKCS1_PADDING);
if (secLen != 16) goto rete;
unsigned char decVerifyToken[162];
int vtLen = RSA_private_decrypt(inp->data.login_server.encryptionresponse.verify_token_length, inp->data.login_server.encryptionresponse.verify_token, decVerifyToken, public_rsa, RSA_PKCS1_PADDING);
int vtLen = RSA_private_decrypt(packet->data.login_server.encryptionresponse.verify_token_length, packet->data.login_server.encryptionresponse.verify_token, decVerifyToken, public_rsa, RSA_PKCS1_PADDING);
if (vtLen != 4) goto rete;
uint32_t vt = *((uint32_t*) decVerifyToken);
if (vt != conn->verifyToken) goto rete;
@ -368,7 +364,7 @@ int handleRead(struct conn* conn, struct work_param* param, int fd) {
if (data == NULL) goto merr;
data += 4;
struct json_object json;
json_parse(&json, data);
json_parse(&json, data);
struct json_object* tmp = json_get(&json, "id");
if (tmp == NULL || tmp->type != JSON_STRING) {
freeJSON(&json);
@ -422,10 +418,10 @@ int handleRead(struct conn* conn, struct work_param* param, int fd) {
conn->disconnect = 1;
goto ret;
}
} else if (inp->id == PKT_LOGIN_SERVER_LOGINSTART) {
} else if (packet->id == PKT_LOGIN_SERVER_LOGINSTART) {
if (online_mode) {
if (conn->verifyToken) goto rete;
conn->onll_username = xstrdup(inp->data.login_server.loginstart.name, 0);
conn->onll_username = xstrdup(packet->data.login_server.loginstart.name, 0);
rep.id = PKT_LOGIN_CLIENT_ENCRYPTIONREQUEST;
rep.data.login_client.encryptionrequest.server_id = "";
rep.data.login_client.encryptionrequest.public_key = public_rsa_publickey;
@ -437,7 +433,7 @@ int handleRead(struct conn* conn, struct work_param* param, int fd) {
if (writePacket(conn, &rep) < 0) goto rete;
} else {
int bn = 0;
char* rna = trim(inp->data.login_server.loginstart.name);
char* rna = trim(packet->data.login_server.loginstart.name);
size_t rnal = strlen(rna);
if (rnal > 16 || rnal < 2) bn = 2;
if (!bn) {
@ -461,7 +457,7 @@ int handleRead(struct conn* conn, struct work_param* param, int fd) {
}
}
} else if (conn->state == STATE_PLAY) {
add_queue(conn->player->incomingPacket, inp);
add_queue(conn->player->incomingPacket, packet);
df = 1;
}
beginProfilerSection("movebuf");
@ -473,20 +469,25 @@ int handleRead(struct conn* conn, struct work_param* param, int fd) {
goto ret;
rete: ;
if (!df) {
freePacket(os, 0, inp);
xfree(inp);
freePacket(os, 0, packet);
xfree(packet);
}
return -1;
ret: ;
if (!df) {
freePacket(os, 0, inp);
xfree(inp);
freePacket(os, 0, packet);
xfree(packet);
}
}
return 0;
}
void connection_on_closed(struct netmgr_connection* conn) {
}
void run_work(struct work_param* param) {
if (pipe(param->pipes) != 0) {
printf("Failed to create pipe! %s\n", strerror(errno));

View File

@ -8,18 +8,11 @@
#ifndef WORK_H_
#define WORK_H_
#include <basin/collection.h>
#include "accept.h"
#include <basin/log.h>
#include <avuna/log.h>
#include <avuna/netmgr.h>
struct work_param {
struct collection* conns;
int pipes[2];
struct logsess* logsess;
int i;
int sport;
};
int connection_read(struct netmgr_connection* conn, uint8_t* read_buf, size_t read_buf_len);
void run_work(struct work_param* param);
void connection_on_closed(struct netmgr_connection* conn);
#endif /* WORK_H_ */

View File

@ -127,37 +127,37 @@ struct chunk* loadRegionChunk(struct region* region, int8_t lchx, int8_t lchz, s
inflateEnd(&strm);
size_t rts = strm.total_out;
struct nbt_tag* nbt = NULL;
if (readNBT(&nbt, rtbuf, rts) < 0) {
if (nbt_read(&nbt, rtbuf, rts) < 0) {
xfree(rtbuf);
return NULL;
}
xfree(rtbuf);
struct nbt_tag* level = getNBTChild(nbt, "Level");
struct nbt_tag* level = nbt_get(nbt, "Level");
if (level == NULL || level->id != NBT_TAG_COMPOUND) goto rerx;
struct nbt_tag* tmp = getNBTChild(level, "xPos");
struct nbt_tag* tmp = nbt_get(level, "xPos");
if (tmp == NULL || tmp->id != NBT_TAG_INT) goto rerx;
int32_t xPos = tmp->data.nbt_int;
tmp = getNBTChild(level, "zPos");
tmp = nbt_get(level, "zPos");
if (tmp == NULL || tmp->id != NBT_TAG_INT) goto rerx;
int32_t zPos = tmp->data.nbt_int;
struct chunk* rch = newChunk(xPos, zPos);
tmp = getNBTChild(level, "LightPopulated");
tmp = nbt_get(level, "LightPopulated");
if (tmp == NULL || tmp->id != NBT_TAG_BYTE) goto rerx;
rch->lightpopulated = tmp->data.nbt_byte;
tmp = getNBTChild(level, "TerrainPopulated");
tmp = nbt_get(level, "TerrainPopulated");
if (tmp == NULL || tmp->id != NBT_TAG_BYTE) goto rerx;
rch->terrainpopulated = tmp->data.nbt_byte;
tmp = getNBTChild(level, "InhabitedTime");
tmp = nbt_get(level, "InhabitedTime");
if (tmp == NULL || tmp->id != NBT_TAG_LONG) goto rerx;
rch->inhabitedticks = tmp->data.nbt_long;
tmp = getNBTChild(level, "Biomes");
tmp = nbt_get(level, "Biomes");
if (tmp == NULL || tmp->id != NBT_TAG_BYTEARRAY) goto rerx;
if (tmp->data.nbt_bytearray.len == 256) memcpy(rch->biomes, tmp->data.nbt_bytearray.data, 256);
tmp = getNBTChild(level, "HeightMap");
tmp = nbt_get(level, "HeightMap");
if (tmp == NULL || tmp->id != NBT_TAG_INTARRAY) goto rerx;
if (tmp->data.nbt_intarray.count == 256) for (int i = 0; i < 256; i++)
rch->heightMap[i >> 4][i & 0x0F] = (uint16_t) tmp->data.nbt_intarray.ints[i];
struct nbt_tag* tes = getNBTChild(level, "TileEntities");
struct nbt_tag* tes = nbt_get(level, "TileEntities");
if (tes == NULL || tes->id != NBT_TAG_LIST) goto rerx;
for (size_t i = 0; i < tes->children_count; i++) {
struct nbt_tag* ten = tes->children[i];
@ -166,13 +166,13 @@ struct chunk* loadRegionChunk(struct region* region, int8_t lchx, int8_t lchz, s
add_collection(rch->tileEntities, te);
}
//TODO: tileticks
struct nbt_tag* sections = getNBTChild(level, "Sections");
struct nbt_tag* sections = nbt_get(level, "Sections");
for (size_t i = 0; i < sections->children_count; i++) {
struct nbt_tag* section = sections->children[i];
tmp = getNBTChild(section, "Y");
tmp = nbt_get(section, "Y");
if (tmp == NULL || tmp->id != NBT_TAG_BYTE) continue;
uint8_t y = tmp->data.nbt_byte;
tmp = getNBTChild(section, "Blocks");
tmp = nbt_get(section, "Blocks");
if (tmp == NULL || tmp->id != NBT_TAG_BYTEARRAY || tmp->data.nbt_bytearray.len != 4096) continue;
int hna = 0;
block* rbl = xmalloc(sizeof(block) * 4096);
@ -181,7 +181,7 @@ struct chunk* loadRegionChunk(struct region* region, int8_t lchx, int8_t lchz, s
if (((block) tmp->data.nbt_bytearray.data[i]) != 0) hna = 1;
}
//if (hna) rch->empty[y] = 0;
tmp = getNBTChild(section, "Add");
tmp = nbt_get(section, "Add");
if (tmp != NULL) {
if (tmp->id != NBT_TAG_BYTEARRAY || tmp->data.nbt_bytearray.len != 2048) continue;
for (int i = 0; i < 4096; i++) {
@ -196,7 +196,7 @@ struct chunk* loadRegionChunk(struct region* region, int8_t lchx, int8_t lchz, s
}
}
if (hna) {
tmp = getNBTChild(section, "Data");
tmp = nbt_get(section, "Data");
if (tmp == NULL || tmp->id != NBT_TAG_BYTEARRAY || tmp->data.nbt_bytearray.len != 2048) continue;
for (int i = 0; i < 4096; i++) {
block sx = tmp->data.nbt_bytearray.data[i / 2];
@ -248,12 +248,12 @@ struct chunk* loadRegionChunk(struct region* region, int8_t lchx, int8_t lchz, s
*((int32_t*) &cs->blocks[bi / 8]) = cv;
bi += cs->bpb;
}
tmp = getNBTChild(section, "BlockLight");
tmp = nbt_get(section, "BlockLight");
if (tmp != NULL) {
if (tmp->id != NBT_TAG_BYTEARRAY || tmp->data.nbt_bytearray.len != 2048) continue;
memcpy(cs->blockLight, tmp->data.nbt_bytearray.data, 2048);
}
tmp = getNBTChild(section, "SkyLight");
tmp = nbt_get(section, "SkyLight");
if (tmp != NULL) {
if (tmp->id != NBT_TAG_BYTEARRAY || tmp->data.nbt_bytearray.len != 2048) continue;
cs->skyLight = xmalloc(2048);
@ -1638,20 +1638,20 @@ int loadWorld(struct world* world, char* path) {
return -1;
}
unsigned char* nld = NULL;
ssize_t ds = decompressNBT(ld, ldi, (void**) &nld);
ssize_t ds = nbt_decompress(ld, ldi, (void**) &nld);
xfree(ld);
if (ds < 0) {
return -1;
}
if (readNBT(&world->level, nld, ds) < 0) return -1;
if (nbt_read(&world->level, nld, ds) < 0) return -1;
xfree(nld);
struct nbt_tag* data = getNBTChild(world->level, "Data");
world->levelType = getNBTChild(data, "generatorName")->data.nbt_string;
world->spawnpos.x = getNBTChild(data, "SpawnX")->data.nbt_int;
world->spawnpos.y = getNBTChild(data, "SpawnY")->data.nbt_int;
world->spawnpos.z = getNBTChild(data, "SpawnZ")->data.nbt_int;
world->time = getNBTChild(data, "DayTime")->data.nbt_long;
world->age = getNBTChild(data, "Time")->data.nbt_long;
struct nbt_tag* data = nbt_get(world->level, "Data");
world->levelType = nbt_get(data, "generatorName")->data.nbt_string;
world->spawnpos.x = nbt_get(data, "SpawnX")->data.nbt_int;
world->spawnpos.y = nbt_get(data, "SpawnY")->data.nbt_int;
world->spawnpos.z = nbt_get(data, "SpawnZ")->data.nbt_int;
world->time = nbt_get(data, "DayTime")->data.nbt_long;
world->age = nbt_get(data, "Time")->data.nbt_long;
world->lpa = xstrdup(path, 0);
printf("spawn: %i, %i, %i\n", world->spawnpos.x, world->spawnpos.y, world->spawnpos.z);
snprintf(lp, PATH_MAX, "%s/region/", path);