mirror of https://github.com/basinserver/basin/
update fuels loader
This commit is contained in:
parent
f714ecea98
commit
9b71e664a1
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
204
src/smelting.c
204
src/smelting.c
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <avuna/log.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "util.h"
|
||||
#include <unistd.h>
|
||||
|
||||
struct mempool* tool_pool;
|
||||
|
|
Loading…
Reference in New Issue