update fuels loader

This commit is contained in:
Protryon 2019-04-17 06:35:36 -07:00
parent f714ecea98
commit 9b71e664a1
9 changed files with 142 additions and 109 deletions

View File

@ -16,7 +16,7 @@
struct smelting_fuel {
int16_t id;
int16_t damage;
int16_t burnTime;
int16_t burn_time;
};
struct smelting_recipe {
@ -24,9 +24,9 @@ struct smelting_recipe {
struct slot output;
};
int16_t getSmeltingFuelBurnTime(struct slot* slot);
int16_t smelting_burnTime(struct slot* slot);
struct slot* getSmeltingOutput(struct slot* input);
struct slot* smelting_output(struct slot* input);
void init_smelting();

View File

@ -550,8 +550,8 @@ void update_furnace(struct world* world, struct tile_entity* te) {
struct slot* si = getSlot(NULL, te->data.furnace.inv, 0);
struct slot* fu = getSlot(NULL, te->data.furnace.inv, 1);
struct slot* aso = getSlot(NULL, te->data.furnace.inv, 2);
struct slot* so = getSmeltingOutput(si);
int16_t st = getSmeltingFuelBurnTime(fu);
struct slot* so = smelting_output(si);
int16_t st = smelting_burnTime(fu);
int burning = 0;
if (so != NULL && ((itemsStackable(so, aso) && (aso->itemCount + so->itemCount) <= maxStackSize(so)) || aso == NULL) && (te->data.furnace.burnTime > 0 || st > 0)) {
burning = 1;
@ -560,7 +560,7 @@ void update_furnace(struct world* world, struct tile_entity* te) {
enableTileEntityTickable(world, te);
setBlockWorld(world, BLK_FURNACE_1 | (getBlockWorld(world, te->x, te->y, te->z) & 0x0f), te->x, te->y, te->z);
}
//printf("bt = %i\n", te->data.furnace.burnTime);
//printf("bt = %i\n", te->data.furnace.burn_time);
if (te->data.furnace.burnTime <= 0 && st > 0 && fu != NULL) {
te->data.furnace.burnTime += st + 1;
if (--fu->itemCount == 0) fu = NULL;

View File

@ -147,7 +147,7 @@ int validItemForSlot(int invtype, int si, struct slot* slot) {
if (si == 0) return 0;
} else if (invtype == INVTYPE_FURNACE) {
if (si == 2) return 0;
else if (si == 1) return getSmeltingFuelBurnTime(slot) > 0;
else if (si == 1) return smelting_burnTime(slot) > 0;
}
return 1;
}

View File

@ -278,17 +278,16 @@ int handle_encryption_response(struct connection* conn, struct packet* packet) {
} else goto ssl_error;
sin.sin_port = htons(443);
sin.sin_family = AF_INET;
int mfd = socket(AF_INET, SOCK_STREAM, 0);
int session_tls_fd = socket(AF_INET, SOCK_STREAM, 0);
SSL* ssl = NULL;
int session_server_successful = 0;
if (mfd < 0) goto ssl_error;
phook(ssl_pool, close_hook, mfd);
if (connect(mfd, (struct sockaddr*) &sin, sizeof(struct sockaddr_in))) goto ssl_error;
if (session_tls_fd < 0) goto ssl_error;
phook(ssl_pool, close_hook, (void*) session_tls_fd);
if (connect(session_tls_fd, (struct sockaddr*) &sin, sizeof(struct sockaddr_in))) goto ssl_error;
ssl = SSL_new(mojang_ctx);
phook(ssl_pool, (void (*)(void*)) SSL_shutdown, ssl);
phook(ssl_pool, (void (*)(void*)) SSL_free, ssl);
SSL_set_connect_state(ssl);
SSL_set_fd(ssl, mfd);
SSL_set_fd(ssl, session_tls_fd);
if (SSL_connect(ssl) != 1) goto ssl_error;
char write_buf[4096];
int write_length = snprintf(write_buf, 1024, "GET /session/minecraft/hasJoined?username=%s&serverId=%s HTTP/1.1\r\nHost: sessionserver.mojang.com\r\nUser-Agent: Basin " VERSION "\r\nConnection: close\r\n\r\n", conn->online_username, hex_hash_signed);
@ -334,22 +333,25 @@ int handle_encryption_response(struct connection* conn, struct packet* packet) {
}
post_map_iteration:;
pthread_rwlock_unlock(&conn->server->players_by_entity_id->rwlock);
session_server_successful = 1;
conn->aes_ctx_enc = EVP_CIPHER_CTX_new();
if (conn->aes_ctx_enc == NULL) goto rete;
if (EVP_EncryptInit_ex(conn->aes_ctx_enc, EVP_aes_128_cfb8(), NULL, conn->shared_secret, conn->shared_secret) != 1) goto rete;
if (EVP_EncryptInit_ex(conn->aes_ctx_enc, EVP_aes_128_cfb8(), NULL, conn->shared_secret, conn->shared_secret) != 1) {
goto ssl_error;
}
if (conn->aes_ctx_enc != NULL) {
phook(conn->pool, (void (*)(void*)) encrypt_free, conn->aes_ctx_enc);
}
conn->aes_ctx_dec = EVP_CIPHER_CTX_new();
if (conn->aes_ctx_dec == NULL) goto rete;
if (EVP_DecryptInit_ex(conn->aes_ctx_dec, EVP_aes_128_cfb8(), NULL, conn->shared_secret, conn->shared_secret) != 1) goto rete;
if (EVP_DecryptInit_ex(conn->aes_ctx_dec, EVP_aes_128_cfb8(), NULL, conn->shared_secret, conn->shared_secret) != 1) {
goto ssl_error;
}
if (conn->aes_ctx_dec != NULL) {
phook(conn->pool, (void (*)(void*)) decrypt_free, conn->aes_ctx_dec);
}
if (work_joinServer(conn, name, id)) {
if (work_joinServer(conn, packet->pool, name, id)) {
pfree(ssl_pool);
return 1;
}

View File

@ -423,6 +423,7 @@ int main(int argc, char* argv[]) {
for (int i = 0; i < overworld->chl_count; i++) {
pthread_create(&tt, NULL, &chunkloadthr, (size_t) i);
}
//TODO: start wake thread
char line[4096];
while (sr > 0) {
if (readLine(STDIN_FILENO, line, 4096) < 0) {

View File

@ -53,6 +53,8 @@ void init_encryption() {
mojang_ctx = SSL_CTX_new(method);
}
// TODO: when we recreate the packet code generator, use 64 bit unambiguous types and uint*/size_t always
void swapEndian(void* dou, size_t ss) {
uint8_t* pxs = (uint8_t*) dou;
for (int i = 0; i < ss / 2; i++) {
@ -252,8 +254,7 @@ void duplicateSlot(struct mempool* pool, struct slot* slot, struct slot* dup) {
dup->item = slot->item;
dup->damage = slot->damage;
dup->itemCount = slot->itemCount;
dup->nbt = pmalloc(struct mempool* pool, sizeof(struct nbt_tag));
duplicateNBT(slot->nbt, dup->nbt);
dup->nbt = nbt_clone(pool, slot->nbt);
}
int writeSlot(struct slot* slot, unsigned char* buffer, size_t buflen) {

View File

@ -740,8 +740,8 @@ void player_receive_packet(struct player* player, struct packet* inp) {
}
} else if (inv->type == INVTYPE_FURNACE) {
if (slot > 2) {
if (getSmeltingOutput(invs) != NULL) swapSlots(player, inv, 0, slot, 0);
else if (getSmeltingFuelBurnTime(invs) > 0) swapSlots(player, inv, 1, slot, 0);
if (smelting_output(invs) != NULL) swapSlots(player, inv, 0, slot, 0);
else if (smelting_burnTime(invs) > 0) swapSlots(player, inv, 1, slot, 0);
else if (slot > 29) {
int r = addInventoryItem(player, inv, invs, 3, 30, 0);
if (r <= 0) setSlot(player, inv, slot, NULL, 0, 1);

View File

@ -7,121 +7,151 @@
#include <basin/smelting.h>
#include <basin/item.h>
#include <basin/globals.h>
#include <avuna/hash.h>
#include <avuna/list.h>
#include <avuna/json.h>
#include <avuna/string.h>
#include <avuna/pmem.h>
#include <avuna/util.h>
#include <avuna/log.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
struct collection* smelting_fuels;
struct hashmap* smelting_fuels; // key = id << 16 | data
struct collection* smelting_recipes;
struct list* smelting_recipes;
int16_t getSmeltingFuelBurnTime(struct slot* slot) {
struct mempool* smelting_pool;
int16_t smelting_burnTime(struct slot* slot) {
if (slot == NULL || slot->item < 0) return 0;
for (size_t i = 0; i < smelting_fuels->size; i++) {
if (smelting_fuels->data[i] == NULL) continue;
struct smelting_fuel* sf = (struct smelting_fuel*) smelting_fuels->data[i];
if (sf->id == slot->item && (sf->damage == -1 || sf->damage == slot->damage)) return sf->burnTime;
uint32_t key = (uint32_t) slot->item << 16u | (uint32_t) slot->damage;
struct smelting_fuel* fuel = hashmap_getint(smelting_fuels, key);
if (fuel == NULL) {
key &= 0xFFFFlu << 16;
key |= 0xFFFF;
fuel = hashmap_getint(smelting_fuels, key);
}
return 0;
if (fuel == NULL) {
return 0;
}
return fuel->burn_time;
}
struct slot* getSmeltingOutput(struct slot* input) {
struct slot* smelting_output(struct slot* input) {
// TODO: use a hashmap
if (input == NULL || input->item < 0) return 0;
for (size_t i = 0; i < smelting_recipes->size; i++) {
pthread_rwlock_init(&smelting_fuels->rwlock);
for (size_t i = 0; i < smelting_recipes->count; i++) {
if (smelting_recipes->data[i] == NULL) continue;
struct smelting_recipe* sf = (struct smelting_recipe*) smelting_recipes->data[i];
if (itemsStackable2(input, &sf->input)) return &sf->output;
if (itemsStackable2(input, &sf->input)) {
pthread_rwlock_unlock(&smelting_fuels->rwlock);
return &sf->output;
}
}
pthread_rwlock_unlock(&smelting_fuels->rwlock);
return 0;
}
void add_smelting_fuel(struct smelting_fuel* fuel) {
add_collection(smelting_fuels, fuel);
uint32_t key = (uint32_t) fuel->id << 16u | (uint32_t) fuel->damage;
hashmap_putint(smelting_fuels, key, fuel);
}
void add_smelting_recipe(struct smelting_recipe* recipe) {
add_collection(smelting_recipes, recipe);
list_append(smelting_recipes, recipe);
}
void init_smelting() {
smelting_fuels = new_collection(128, 0);
smelting_recipes = new_collection(128, 0);
char* jsf = xmalloc(4097);
size_t jsfs = 4096;
size_t jsr = 0;
int fd = open("smelting.json", O_RDONLY);
ssize_t r = 0;
while ((r = read(fd, jsf + jsr, jsfs - jsr)) > 0) {
jsr += r;
if (jsfs - jsr < 512) {
jsfs += 4096;
jsf = xrealloc(jsf, jsfs + 1);
}
smelting_pool = mempool_new();
smelting_fuels = hashmap_thread_new(64, smelting_pool);
smelting_recipes = list_thread_new(128, smelting_pool);
char* json_file = (char*) read_file_fully(smelting_pool, "smelting.json", NULL);
if (json_file == NULL) {
errlog(delog, "Error reading smelting data: %s\n", strerror(errno));
return;
}
struct json_object* json = NULL;
json_parse(smelting_pool, &json, json_file);
pprefree(smelting_pool, json_file);
struct json_object* fuels = json_get(json, "fuels");
if (fuels == NULL || fuels->type != JSON_OBJECT) goto format_error_json;
struct json_object* recipes = json_get(json, "recipes");
if (recipes == NULL || recipes->type != JSON_OBJECT) goto format_error_json;
ITER_LLIST(fuels->children_list, value) {
struct json_object* child_json = value;
struct json_object* id_json = json_get(child_json, "id");
if (id_json == NULL || id_json->type != JSON_NUMBER) {
goto fuel_format_error;
}
struct smelting_fuel* fuel = pcalloc(smelting_pool, sizeof(struct smelting_fuel));
fuel->id = (int16_t) id_json->data.number;
if (fuel->id <= 0) {
goto fuel_format_error;
}
struct json_object* damage_json = json_get(child_json, "damage");
if (damage_json == NULL || damage_json->type != JSON_NUMBER) {
goto fuel_format_error;
}
fuel->damage = (int16_t) damage_json->data.number;
struct json_object* burn_time_json = json_get(child_json, "burnTime");
if (burn_time_json == NULL || burn_time_json->type != JSON_NUMBER) {
goto fuel_format_error;
}
fuel->burn_time = (int16_t) burn_time_json->data.number;
add_smelting_fuel(fuel);
continue;
fuel_format_error:;
printf("[WARNING] Error Loading Smelting Fuel \"%s\"! Skipped.\n", child_json->name);
ITER_LLIST_END();
}
jsf[jsr] = 0;
if (r < 0) {
printf("Error reading smelting information: %s\n", strerror(errno));
ITER_LLIST(recipes->children_list, value) {
struct json_object* child_json = value;
struct smelting_recipe* recipe = pcalloc(smelting_pool, sizeof(struct smelting_recipe));
struct json_object* input_json = json_get(child_json, "input_item");
if (input_json == NULL || input_json->type != JSON_NUMBER) {
goto format_error_recipe;
}
recipe->input.item = (int16_t) input_json->data.number;
if (recipe->input.item <= 0) goto format_error_recipe;
struct json_object* input_damage_json = json_get(child_json, "input_damage");
if (input_damage_json == NULL || input_damage_json->type != JSON_NUMBER) {
goto format_error_recipe;
}
recipe->input.damage = (int16_t) input_damage_json->data.number;
recipe->input.itemCount = 1;
recipe->input.nbt = NULL;
struct json_object* output_json = json_get(child_json, "output_item");
if (output_json == NULL || output_json->type != JSON_NUMBER) {
goto format_error_recipe;
}
recipe->output.item = (int16_t) output_json->data.number;
if (recipe->output.item <= 0) {
goto format_error_recipe;
}
struct json_object* output_damage_json = json_get(child_json, "output_damage");
if (output_damage_json == NULL || output_damage_json->type != JSON_NUMBER) {
goto format_error_recipe;
}
recipe->output.damage = (int16_t) output_damage_json->data.number;
struct json_object* output_count_json = json_get(child_json, "output_count");
if (output_count_json == NULL || output_count_json->type != JSON_NUMBER) {
goto format_error_recipe;
}
recipe->output.itemCount = (uint8_t) output_count_json->data.number;
recipe->output.nbt = NULL;
add_smelting_recipe(recipe);
continue;
format_error_recipe:;
printf("[WARNING] Error Loading Smelting Recipe \"%s\"! Skipped.\n", child_json->name);
ITER_LLIST_END();
}
close(fd);
struct json_object json;
json_parse(&json, jsf);
struct json_object* fuels = json_get(&json, "fuels");
if (fuels == NULL || fuels->type != JSON_OBJECT) goto cerr2;
struct json_object* recipes = json_get(&json, "recipes");
if (recipes == NULL || recipes->type != JSON_OBJECT) goto cerr2;
for (size_t i = 0; i < fuels->child_count; i++) {
struct json_object* ur = fuels->children[i];
struct smelting_fuel* ii = xcalloc(sizeof(struct smelting_fuel));
struct json_object* tmp = json_get(ur, "id");
if (tmp == NULL || tmp->type != JSON_NUMBER) goto cerr;
ii->id = (int16_t) tmp->data.number;
if (ii->id <= 0) goto cerr;
tmp = json_get(ur, "damage");
if (tmp == NULL || tmp->type != JSON_NUMBER) goto cerr;
ii->damage = (int16_t) tmp->data.number;
tmp = json_get(ur, "burnTime");
if (tmp == NULL || tmp->type != JSON_NUMBER) goto cerr;
ii->burnTime = (int16_t) tmp->data.number;
add_smelting_fuel(ii);
continue;
cerr: ;
printf("[WARNING] Error Loading Smelting Fuel \"%s\"! Skipped.\n", ur->name);
}
for (size_t i = 0; i < recipes->child_count; i++) {
struct json_object* ur = recipes->children[i];
struct smelting_recipe* ii = xcalloc(sizeof(struct smelting_recipe));
struct json_object* tmp = json_get(ur, "input_item");
if (tmp == NULL || tmp->type != JSON_NUMBER) goto cerr3;
ii->input.item = (int16_t) tmp->data.number;
if (ii->input.item <= 0) goto cerr3;
tmp = json_get(ur, "input_damage");
if (tmp == NULL || tmp->type != JSON_NUMBER) goto cerr3;
ii->input.damage = (int16_t) tmp->data.number;
ii->input.itemCount = 1;
ii->input.nbt = NULL;
tmp = json_get(ur, "output_item");
if (tmp == NULL || tmp->type != JSON_NUMBER) goto cerr3;
ii->output.item = (int16_t) tmp->data.number;
if (ii->output.item <= 0) goto cerr3;
tmp = json_get(ur, "output_damage");
if (tmp == NULL || tmp->type != JSON_NUMBER) goto cerr3;
ii->output.damage = (int16_t) tmp->data.number;
tmp = json_get(ur, "output_count");
if (tmp == NULL || tmp->type != JSON_NUMBER) goto cerr3;
ii->output.itemCount = (uint8_t) tmp->data.number;
ii->output.nbt = NULL;
add_smelting_recipe(ii);
continue;
cerr3: ;
printf("[WARNING] Error Loading Smelting Recipe \"%s\"! Skipped.\n", ur->name);
}
freeJSON(&json);
xfree(jsf);
pfree(json->pool);
return;
cerr2: ;
freeJSON(&json);
xfree(jsf);
format_error_json: ;
pfree(json->pool);
printf("[ERROR] Critical Failure Loading 'smelting.json', No Fuels/Recipes Object!\n");
}

View File

@ -18,7 +18,6 @@
#include <avuna/log.h>
#include <fcntl.h>
#include <errno.h>
#include "util.h"
#include <unistd.h>
struct mempool* tool_pool;