mirror of https://github.com/basinserver/basin/
player refactoring
This commit is contained in:
parent
8d539f1fd0
commit
7008a54132
|
@ -46,7 +46,7 @@ void broadcast(char* text, char* color);
|
||||||
void broadcastf(char* color, char* fmt, ...);
|
void broadcastf(char* color, char* fmt, ...);
|
||||||
|
|
||||||
#define BEGIN_BROADCAST(players) pthread_rwlock_rdlock(&(players)->rwlock); ITER_MAP(players) { struct player* bc_player = (struct player*)value; {
|
#define BEGIN_BROADCAST(players) pthread_rwlock_rdlock(&(players)->rwlock); ITER_MAP(players) { struct player* bc_player = (struct player*)value; {
|
||||||
#define BEGIN_BROADCAST_DIST(distfrom, dist) pthread_rwlock_rdlock(&(players)->rwlock); ITER_MAP(distfrom->world->players) { struct player* bc_player = (struct player*)value; if(entity_distsq(bc_player->entity, distfrom) < dist * dist) {
|
#define BEGIN_BROADCAST_DIST(distfrom, dist) pthread_rwlock_rdlock(&(distfrom->world->players)->rwlock); ITER_MAP(distfrom->world->players) { struct player* bc_player = (struct player*)value; if(entity_distsq(bc_player->entity, distfrom) < dist * dist) {
|
||||||
#define BEGIN_BROADCAST_DISTXYZ(x, y, z, players, dist) pthread_rwlock_rdlock(&(players)->rwlock); ITER_MAP(players) { struct player* bc_player = (struct player*)value; if (entity_distsq_block(bc_player->entity, x, y, z) < dist * dist) {
|
#define BEGIN_BROADCAST_DISTXYZ(x, y, z, players, dist) pthread_rwlock_rdlock(&(players)->rwlock); ITER_MAP(players) { struct player* bc_player = (struct player*)value; if (entity_distsq_block(bc_player->entity, x, y, z) < dist * dist) {
|
||||||
#define BEGIN_BROADCAST_EXCEPT(players, except) pthread_rwlock_rdlock(&(players)->rwlock); ITER_MAP(players) { struct player* bc_player = (struct player*)value; if (bc_player != except) {
|
#define BEGIN_BROADCAST_EXCEPT(players, except) pthread_rwlock_rdlock(&(players)->rwlock); ITER_MAP(players) { struct player* bc_player = (struct player*)value; if (bc_player != except) {
|
||||||
#define BEGIN_BROADCAST_EXCEPT_DIST(except, distfrom, dist) pthread_rwlock_rdlock(&(distfrom->world->players)->rwlock); ITER_MAP(distfrom->world->players) { struct player* bc_player = (struct player*)value; if (bc_player != except && entity_distsq(bc_player->entity, distfrom) < dist * dist) {
|
#define BEGIN_BROADCAST_EXCEPT_DIST(except, distfrom, dist) pthread_rwlock_rdlock(&(distfrom->world->players)->rwlock); ITER_MAP(distfrom->world->players) { struct player* bc_player = (struct player*)value; if (bc_player != except && entity_distsq(bc_player->entity, distfrom) < dist * dist) {
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
#ifndef BASIN_NETWORK_H_
|
#ifndef BASIN_NETWORK_H_
|
||||||
#define BASIN_NETWORK_H_
|
#define BASIN_NETWORK_H_
|
||||||
|
|
||||||
#include <basin/inventory.h>
|
|
||||||
#include <avuna/pmem.h>
|
#include <avuna/pmem.h>
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
|
struct slot;
|
||||||
struct packet;
|
struct packet;
|
||||||
|
|
||||||
struct __attribute__((__packed__)) encpos {
|
struct __attribute__((__packed__)) encpos {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <basin/network.h>
|
#include <basin/network.h>
|
||||||
#include <basin/block.h>
|
#include <basin/block.h>
|
||||||
#include <basin/connection.h>
|
#include <basin/connection.h>
|
||||||
|
#include <basin/world.h>
|
||||||
#include <avuna/pmem.h>
|
#include <avuna/pmem.h>
|
||||||
|
|
||||||
struct player {
|
struct player {
|
||||||
|
@ -30,7 +31,7 @@ struct player {
|
||||||
struct queue* incoming_packets;
|
struct queue* incoming_packets;
|
||||||
uint32_t next_keep_alive;
|
uint32_t next_keep_alive;
|
||||||
uint8_t spawned_in;
|
uint8_t spawned_in;
|
||||||
uint32_t chunks_sent
|
uint32_t chunks_sent;
|
||||||
uint8_t trigger_rechunk;
|
uint8_t trigger_rechunk;
|
||||||
|
|
||||||
struct inventory* inventory;
|
struct inventory* inventory;
|
||||||
|
@ -50,7 +51,7 @@ struct player {
|
||||||
int32_t xptotal;
|
int32_t xptotal;
|
||||||
int32_t xplevel;
|
int32_t xplevel;
|
||||||
int32_t score;
|
int32_t score;
|
||||||
size_t last_teleport_id;
|
int32_t last_teleport_id;
|
||||||
int8_t sleeping;
|
int8_t sleeping;
|
||||||
int16_t fire;
|
int16_t fire;
|
||||||
//TODO: enderitems inventory
|
//TODO: enderitems inventory
|
||||||
|
@ -76,13 +77,9 @@ void player_hungerUpdate(struct player* player);
|
||||||
|
|
||||||
void player_send_entity_move(struct player* player, struct entity* entity);
|
void player_send_entity_move(struct player* player, struct entity* entity);
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
void player_receive_packet(struct player* player, struct packet* inp);
|
void player_receive_packet(struct player* player, struct packet* inp);
|
||||||
|
|
||||||
void player_tick(struct world* world, struct player* player);
|
|
||||||
=======
|
|
||||||
void player_tick(struct player* player);
|
void player_tick(struct player* player);
|
||||||
>>>>>>> 0a05322... tweaks
|
|
||||||
|
|
||||||
void player_kick(struct player* player, char* message);
|
void player_kick(struct player* player, char* message);
|
||||||
|
|
||||||
|
@ -94,7 +91,7 @@ float player_getAttackStrength(struct player* player, float adjust);
|
||||||
|
|
||||||
void player_teleport(struct player* player, double x, double y, double z);
|
void player_teleport(struct player* player, double x, double y, double z);
|
||||||
|
|
||||||
struct player* player_get_by_name(char* name);
|
struct player* player_get_by_name(struct server* server, char* name);
|
||||||
|
|
||||||
void player_set_gamemode(struct player* player, int gamemode);
|
void player_set_gamemode(struct player* player, int gamemode);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <basin/network.h>
|
#include <basin/network.h>
|
||||||
#include <basin/biome.h>
|
#include <basin/biome.h>
|
||||||
#include <basin/chunk.h>
|
#include <basin/chunk.h>
|
||||||
|
#include <basin/network.h>
|
||||||
#include <basin/region.h>
|
#include <basin/region.h>
|
||||||
#include <basin/boundingbox.h>
|
#include <basin/boundingbox.h>
|
||||||
#include <basin/block.h>
|
#include <basin/block.h>
|
||||||
|
@ -72,6 +73,9 @@ struct world {
|
||||||
uint64_t seed;
|
uint64_t seed;
|
||||||
struct perlin perlin;
|
struct perlin perlin;
|
||||||
struct queue* chunk_requests;
|
struct queue* chunk_requests;
|
||||||
|
// locked under chunk_requests mutex
|
||||||
|
struct mempool* chunk_request_pool;
|
||||||
|
size_t tick_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
// "*_guess" functions accept a chunk guess and call the proper function if the chunk is a miss. used to optimize chunk lookups in intensive local algorithms. probably overused.
|
// "*_guess" functions accept a chunk guess and call the proper function if the chunk is a miss. used to optimize chunk lookups in intensive local algorithms. probably overused.
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
#include <avuna/string.h>
|
#include <avuna/string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void command_gamemode(struct player* player, char** args, size_t args_count) {
|
void command_gamemode(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (player != NULL) return;
|
if (player != NULL) return;
|
||||||
if (args_count == 0 || args_count > 2) {
|
if (args_count == 0 || args_count > 2) {
|
||||||
sendMessageToPlayer(player, "Usage: /gamemode <gamemode> [player]", "red");
|
sendMessageToPlayer(player, "Usage: /gamemode <gamemode> [player]", "red");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct player* target = player;
|
struct player* target = player;
|
||||||
if (args_count == 2) target = player_get_by_name(args[1]);
|
if (args_count == 2) target = player_get_by_name(player->server, args[1]);
|
||||||
if (target == NULL) {
|
if (target == NULL) {
|
||||||
sendMessageToPlayer(player, "[ERROR] No such player found.", "red");
|
sendMessageToPlayer(player, "[ERROR] No such player found.", "red");
|
||||||
return;
|
return;
|
||||||
|
@ -38,14 +38,14 @@ void command_gamemode(struct player* player, char** args, size_t args_count) {
|
||||||
sendMessageToPlayer(NULL, "Done.", "default");
|
sendMessageToPlayer(NULL, "Done.", "default");
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_tp(struct player* player, char** args, size_t args_count) {
|
void command_tp(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (player != NULL) return;
|
if (player != NULL) return;
|
||||||
if (args_count == 0 || args_count > 4) {
|
if (args_count == 0 || args_count > 4) {
|
||||||
sendMessageToPlayer(player, "Usage: /tp <to> OR /tp <from> <to> or <x> <y> <z> or <player> <x> <y> <z>", "red");
|
sendMessageToPlayer(player, "Usage: /tp <to> OR /tp <from> <to> or <x> <y> <z> or <player> <x> <y> <z>", "red");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (args_count >= 3) {
|
if (args_count >= 3) {
|
||||||
struct player* from = args_count == 3 ? player : player_get_by_name(args[0]);
|
struct player* from = args_count == 3 ? player : player_get_by_name(server, args[0]);
|
||||||
if (from == NULL) {
|
if (from == NULL) {
|
||||||
sendMessageToPlayer(player, "[ERROR] No such player found.", "red");
|
sendMessageToPlayer(player, "[ERROR] No such player found.", "red");
|
||||||
return;
|
return;
|
||||||
|
@ -53,8 +53,8 @@ void command_tp(struct player* player, char** args, size_t args_count) {
|
||||||
int32_t ai = args_count == 4 ? 1 : 0;
|
int32_t ai = args_count == 4 ? 1 : 0;
|
||||||
player_teleport(from, strtol(args[ai++], NULL, 10), strtol(args[ai++], NULL, 10), strtol(args[ai++], NULL, 10));
|
player_teleport(from, strtol(args[ai++], NULL, 10), strtol(args[ai++], NULL, 10), strtol(args[ai++], NULL, 10));
|
||||||
} else {
|
} else {
|
||||||
struct player* from = args_count == 1 ? player : player_get_by_name(args[0]);
|
struct player* from = args_count == 1 ? player : player_get_by_name(server, args[0]);
|
||||||
struct player* to = args_count == 1 ? player_get_by_name(args[0]) : player_get_by_name(args[1]);
|
struct player* to = args_count == 1 ? player_get_by_name(server, args[0]) : player_get_by_name(server, args[1]);
|
||||||
if (from == NULL || to == NULL) {
|
if (from == NULL || to == NULL) {
|
||||||
sendMessageToPlayer(player, "[ERROR] No such player found.", "red");
|
sendMessageToPlayer(player, "[ERROR] No such player found.", "red");
|
||||||
return;
|
return;
|
||||||
|
@ -67,13 +67,13 @@ void command_tp(struct player* player, char** args, size_t args_count) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_kick(struct player* player, char** args, size_t args_count) {
|
void command_kick(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (player != NULL) return;
|
if (player != NULL) return;
|
||||||
if (args_count == 0 || args_count > 2) {
|
if (args_count == 0 || args_count > 2) {
|
||||||
sendMessageToPlayer(player, "Usage: /kick <player> OR /kick <player> \"<reason>\"", "red");
|
sendMessageToPlayer(player, "Usage: /kick <player> OR /kick <player> \"<reason>\"", "red");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct player* target = player_get_by_name(args[0]);
|
struct player* target = player_get_by_name(server, args[0]);
|
||||||
if (target == NULL) {
|
if (target == NULL) {
|
||||||
sendMessageToPlayer(player, "[ERROR] No such player found.", "red");
|
sendMessageToPlayer(player, "[ERROR] No such player found.", "red");
|
||||||
return;
|
return;
|
||||||
|
@ -82,7 +82,7 @@ void command_kick(struct player* player, char** args, size_t args_count) {
|
||||||
player_kick(target, reason);
|
player_kick(target, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_say(struct player* player, char** args, size_t args_count) {
|
void command_say(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (player != NULL) return;
|
if (player != NULL) return;
|
||||||
if (args_count != 1) {
|
if (args_count != 1) {
|
||||||
sendMessageToPlayer(player, "Usage: /say \"<message>\"", "red");
|
sendMessageToPlayer(player, "Usage: /say \"<message>\"", "red");
|
||||||
|
@ -91,19 +91,20 @@ void command_say(struct player* player, char** args, size_t args_count) {
|
||||||
broadcastf("light_purple", "CONSOLE: %s", args[0]);
|
broadcastf("light_purple", "CONSOLE: %s", args[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_motd(struct player* player, char** args, size_t args_count) {
|
void command_motd(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (player != NULL) return;
|
if (player != NULL) return;
|
||||||
if (args_count != 1) {
|
if (args_count != 1) {
|
||||||
sendMessageToPlayer(NULL, "Usage: /motd \"<message>\"", "red");
|
sendMessageToPlayer(NULL, "Usage: /motd \"<message>\"", "red");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sendMessageToPlayer(NULL, "Done.", "default");
|
sendMessageToPlayer(NULL, "Done.", "default");
|
||||||
xfree (motd);
|
server->motd = prealloc(global_pool, server->motd, strlen(args[0]) + 1);
|
||||||
motd = xstrdup(args[0], 0);
|
server->motd[strlen(args[0])] = 0;
|
||||||
|
memcpy(server->motd, args[0], strlen(args[0]) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_list(struct player* player, char** args, size_t args_count) {
|
void command_list(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
char* plist = xmalloc(players->entry_count * 18 + 30);
|
char* plist = pmalloc();
|
||||||
char* cptr = plist;
|
char* cptr = plist;
|
||||||
BEGIN_HASHMAP_ITERATION (players)
|
BEGIN_HASHMAP_ITERATION (players)
|
||||||
if (cptr > plist) {
|
if (cptr > plist) {
|
||||||
|
|
|
@ -5,9 +5,7 @@
|
||||||
* Author: root
|
* Author: root
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "basin/packet.h"
|
#include <basin/packet.h>
|
||||||
#include <basin/basin.h>
|
|
||||||
#include <basin/queue.h>
|
|
||||||
#include <basin/game.h>
|
#include <basin/game.h>
|
||||||
#include <basin/crafting.h>
|
#include <basin/crafting.h>
|
||||||
#include <basin/smelting.h>
|
#include <basin/smelting.h>
|
||||||
|
@ -18,6 +16,7 @@
|
||||||
#include <basin/profile.h>
|
#include <basin/profile.h>
|
||||||
#include <basin/anticheat.h>
|
#include <basin/anticheat.h>
|
||||||
#include <avuna/hash.h>
|
#include <avuna/hash.h>
|
||||||
|
#include <avuna/queue.h>
|
||||||
#include <avuna/string.h>
|
#include <avuna/string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
|
@ -354,7 +354,6 @@ int main(int argc, char* argv[]) {
|
||||||
errlog(delog, "Only one server block is supported at this time.");
|
errlog(delog, "Only one server block is supported at this time.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
globalChunkQueue = queue_new(0, 1, global_pool);
|
|
||||||
init_materials();
|
init_materials();
|
||||||
acclog(delog, "Materials Initialized");
|
acclog(delog, "Materials Initialized");
|
||||||
init_blocks();
|
init_blocks();
|
||||||
|
|
388
src/player.c
388
src/player.c
|
@ -23,6 +23,16 @@
|
||||||
#include <avuna/pmem.h>
|
#include <avuna/pmem.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
void player_cleanup(struct player* player) {
|
||||||
|
struct packet* pkt = NULL;
|
||||||
|
while ((pkt = queue_maybepop(player->incoming_packets)) != NULL) {
|
||||||
|
pfree(pkt->pool);
|
||||||
|
}
|
||||||
|
while ((pkt = queue_maybepop(player->outgoing_packets)) != NULL) {
|
||||||
|
pfree(pkt->pool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct player* player_new(struct mempool* parent, struct server* server, struct connection* conn, struct world* world, struct entity* entity, char* name, struct uuid uuid, uint8_t gamemode) {
|
struct player* player_new(struct mempool* parent, struct server* server, struct connection* conn, struct world* world, struct entity* entity, char* name, struct uuid uuid, uint8_t gamemode) {
|
||||||
struct mempool* pool = mempool_new();
|
struct mempool* pool = mempool_new();
|
||||||
pchild(parent, pool);
|
pchild(parent, pool);
|
||||||
|
@ -46,10 +56,11 @@ struct player* player_new(struct mempool* parent, struct server* server, struct
|
||||||
player->loaded_entities = hashmap_thread_new(128, player->pool);
|
player->loaded_entities = hashmap_thread_new(128, player->pool);
|
||||||
player->incoming_packets = queue_new(0, 1, player->pool);
|
player->incoming_packets = queue_new(0, 1, player->pool);
|
||||||
player->outgoing_packets = queue_new(0, 1, player->pool);
|
player->outgoing_packets = queue_new(0, 1, player->pool);
|
||||||
player->lastSwing = player->server->tick_counter;
|
player->lastSwing = player->world->tick_counter;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
player->reachDistance = 6.f;
|
player->reachDistance = 6.f;
|
||||||
|
phook(player->pool, player_cleanup, player);
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,9 +68,8 @@ void player_send_entity_move(struct player* player, struct entity* entity) {
|
||||||
double dist = entity_distsq_block(entity, entity->last_x, entity->last_y, entity->last_z);
|
double dist = entity_distsq_block(entity, entity->last_x, entity->last_y, entity->last_z);
|
||||||
double delta_rotation = (entity->yaw - entity->last_yaw) * (entity->yaw - entity->last_yaw) + (entity->pitch - entity->last_pitch) * (entity->pitch - entity->last_pitch);
|
double delta_rotation = (entity->yaw - entity->last_yaw) * (entity->yaw - entity->last_yaw) + (entity->pitch - entity->last_pitch) * (entity->pitch - entity->last_pitch);
|
||||||
|
|
||||||
//printf("mp = %f, md = %f\n", mp, md);
|
|
||||||
if ((dist > .001 || delta_rotation > .01 || entity->type == ENT_PLAYER)) {
|
if ((dist > .001 || delta_rotation > .01 || entity->type == ENT_PLAYER)) {
|
||||||
int force_update = player->server->tick_counter % 200 == 0 || (entity->type == ENT_PLAYER && entity->data.player.player->last_teleport_id != 0);
|
int force_update = player->world->tick_counter % 200 == 0 || (entity->type == ENT_PLAYER && entity->data.player.player->last_teleport_id != 0);
|
||||||
if (!force_update && dist <= .001 && delta_rotation <= .01) {
|
if (!force_update && dist <= .001 && delta_rotation <= .01) {
|
||||||
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_ENTITY);
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_ENTITY);
|
||||||
pkt->data.play_client.entity.entity_id = entity->id;
|
pkt->data.play_client.entity.entity_id = entity->id;
|
||||||
|
@ -140,7 +150,7 @@ void player_tick(struct player* player) {
|
||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
player->chunks_sent = 0;
|
player->chunks_sent = 0;
|
||||||
if (player->server->tick_counter % 200 == 0) {
|
if (player->world->tick_counter % 200 == 0) {
|
||||||
if (player->next_keep_alive != 0) {
|
if (player->next_keep_alive != 0) {
|
||||||
player->conn->disconnect = 1;
|
player->conn->disconnect = 1;
|
||||||
return;
|
return;
|
||||||
|
@ -148,7 +158,7 @@ void player_tick(struct player* player) {
|
||||||
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_KEEPALIVE);
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_KEEPALIVE);
|
||||||
pkt->data.play_client.keepalive.keep_alive_id = rand();
|
pkt->data.play_client.keepalive.keep_alive_id = rand();
|
||||||
queue_push(player->outgoing_packets, pkt);
|
queue_push(player->outgoing_packets, pkt);
|
||||||
} else if (player->server->tick_counter % 200 == 100) {
|
} else if (player->world->tick_counter % 200 == 100) {
|
||||||
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_TIMEUPDATE);
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_TIMEUPDATE);
|
||||||
pkt->data.play_client.timeupdate.time_of_day = player->world->time;
|
pkt->data.play_client.timeupdate.time_of_day = player->world->time;
|
||||||
pkt->data.play_client.timeupdate.world_age = player->world->age;
|
pkt->data.play_client.timeupdate.world_age = player->world->age;
|
||||||
|
@ -203,14 +213,14 @@ void player_tick(struct player* player) {
|
||||||
int32_t last_chunk_z = ((int32_t) player->entity->last_z >> 4);
|
int32_t last_chunk_z = ((int32_t) player->entity->last_z >> 4);
|
||||||
if (player->loaded_chunks->entry_count == 0 || player->trigger_rechunk) { // || tick_counter % 200 == 0
|
if (player->loaded_chunks->entry_count == 0 || player->trigger_rechunk) { // || tick_counter % 200 == 0
|
||||||
beginProfilerSection("chunkLoading_tick");
|
beginProfilerSection("chunkLoading_tick");
|
||||||
pthread_mutex_lock(&player->chunkRequests->data_mutex);
|
pthread_mutex_lock(&player->world->chunk_requests->data_mutex);
|
||||||
int first_chunks = player->loaded_chunks->entry_count == 0 || player->trigger_rechunk;
|
int first_chunks = player->loaded_chunks->entry_count == 0 || player->trigger_rechunk;
|
||||||
if (player->trigger_rechunk) {
|
if (player->trigger_rechunk) {
|
||||||
pthread_rwlock_rdlock(&player->loaded_chunks->rwlock);
|
pthread_rwlock_rdlock(&player->loaded_chunks->rwlock);
|
||||||
ITER_MAP(player->loaded_chunks) {
|
ITER_MAP(player->loaded_chunks) {
|
||||||
struct chunk* chunk = (struct chunk*) value;
|
struct chunk* chunk = (struct chunk*) value;
|
||||||
if (chunk->x < chunk_x - CHUNK_VIEW_DISTANCE || chunk->x > chunk_x + CHUNK_VIEW_DISTANCE || chunk->z < chunk_z - CHUNK_VIEW_DISTANCE || chunk->z > chunk_z + CHUNK_VIEW_DISTANCE) {
|
if (chunk->x < chunk_x - CHUNK_VIEW_DISTANCE || chunk->x > chunk_x + CHUNK_VIEW_DISTANCE || chunk->z < chunk_z - CHUNK_VIEW_DISTANCE || chunk->z > chunk_z + CHUNK_VIEW_DISTANCE) {
|
||||||
struct chunk_request* request = pcalloc(player->world->pool, sizeof(struct chunk_request));
|
struct chunk_request* request = pcalloc(player->world->chunk_request_pool, sizeof(struct chunk_request));
|
||||||
request->chunk_x = chunk->x;
|
request->chunk_x = chunk->x;
|
||||||
request->chunk_z = chunk->z;
|
request->chunk_z = chunk->z;
|
||||||
request->world = player->world;
|
request->world = player->world;
|
||||||
|
@ -225,13 +235,13 @@ void player_tick(struct player* player) {
|
||||||
int32_t x = chunk_x - r;
|
int32_t x = chunk_x - r;
|
||||||
int32_t z = chunk_z - r;
|
int32_t z = chunk_z - r;
|
||||||
for (int i = 0; i < ((r == 0) ? 1 : (r * 8)); i++) {
|
for (int i = 0; i < ((r == 0) ? 1 : (r * 8)); i++) {
|
||||||
if (first_chunks || !contains_hashmap(player->loaded_chunks, chunk_get_key_direct(x, z))) {
|
if (first_chunks || !hashmap_getint(player->loaded_chunks, chunk_get_key_direct(x, z))) {
|
||||||
struct chunk_request* cr = xmalloc(sizeof(struct chunk_request));
|
struct chunk_request* request = pcalloc(player->world->chunk_request_pool, sizeof(struct chunk_request));
|
||||||
cr->chunk_x = x;
|
request->chunk_x = x;
|
||||||
cr->chunk_z = z;
|
request->chunk_z = z;
|
||||||
cr->world = world;
|
request->world = player->world;
|
||||||
cr->load = 1;
|
request->load = 1;
|
||||||
add_queue(player->chunkRequests, cr);
|
queue_push(player->world->chunk_requests, request);
|
||||||
}
|
}
|
||||||
if (i < 2 * r) x++;
|
if (i < 2 * r) x++;
|
||||||
else if (i < 4 * r) z++;
|
else if (i < 4 * r) z++;
|
||||||
|
@ -239,53 +249,51 @@ void player_tick(struct player* player) {
|
||||||
else if (i < 8 * r) z--;
|
else if (i < 8 * r) z--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&player->chunkRequests->data_mutex);
|
pthread_mutex_unlock(&player->world->chunk_requests->data_mutex);
|
||||||
player->triggerRechunk = 0;
|
player->trigger_rechunk = 0;
|
||||||
pthread_cond_signal(&chunk_wake);
|
|
||||||
endProfilerSection("chunkLoading_tick");
|
endProfilerSection("chunkLoading_tick");
|
||||||
}
|
}
|
||||||
if (last_chunk_x != chunk_x || last_chunk_z != chunk_z) {
|
if (last_chunk_x != chunk_x || last_chunk_z != chunk_z) {
|
||||||
pthread_mutex_lock(&player->chunkRequests->data_mutex);
|
pthread_mutex_lock(&player->world->chunk_requests->data_mutex);
|
||||||
for (int32_t fx = last_chunk_x; last_chunk_x < chunk_x ? (fx < chunk_x) : (fx > chunk_x); last_chunk_x < chunk_x ? fx++ : fx--) {
|
for (int32_t fx = last_chunk_x; last_chunk_x < chunk_x ? (fx < chunk_x) : (fx > chunk_x); last_chunk_x < chunk_x ? fx++ : fx--) {
|
||||||
for (int32_t fz = last_chunk_z - CHUNK_VIEW_DISTANCE; fz <= last_chunk_z + CHUNK_VIEW_DISTANCE; fz++) {
|
for (int32_t fz = last_chunk_z - CHUNK_VIEW_DISTANCE; fz <= last_chunk_z + CHUNK_VIEW_DISTANCE; fz++) {
|
||||||
beginProfilerSection("chunkUnloading_live");
|
beginProfilerSection("chunkUnloading_live");
|
||||||
struct chunk_request* cr = xmalloc(sizeof(struct chunk_request));
|
struct chunk_request* request = pcalloc(player->world->chunk_request_pool, sizeof(struct chunk_request));
|
||||||
cr->chunk_x = last_chunk_x < chunk_x ? (fx - CHUNK_VIEW_DISTANCE) : (fx + CHUNK_VIEW_DISTANCE);
|
request->chunk_x = last_chunk_x < chunk_x ? (fx - CHUNK_VIEW_DISTANCE) : (fx + CHUNK_VIEW_DISTANCE);
|
||||||
cr->chunk_z = fz;
|
request->chunk_z = fz;
|
||||||
cr->load = 0;
|
request->load = 0;
|
||||||
add_queue(player->chunkRequests, cr);
|
queue_push(player->world->chunk_requests, request);
|
||||||
endProfilerSection("chunkUnloading_live");
|
endProfilerSection("chunkUnloading_live");
|
||||||
beginProfilerSection("chunkLoading_live");
|
beginProfilerSection("chunkLoading_live");
|
||||||
cr = xmalloc(sizeof(struct chunk_request));
|
request = pcalloc(player->world->chunk_request_pool, sizeof(struct chunk_request));
|
||||||
cr->chunk_x = last_chunk_x < chunk_x ? (fx + CHUNK_VIEW_DISTANCE) : (fx - CHUNK_VIEW_DISTANCE);
|
request->chunk_x = last_chunk_x < chunk_x ? (fx + CHUNK_VIEW_DISTANCE) : (fx - CHUNK_VIEW_DISTANCE);
|
||||||
cr->chunk_z = fz;
|
request->chunk_z = fz;
|
||||||
cr->world = world;
|
request->world = player->world;
|
||||||
cr->load = 1;
|
request->load = 1;
|
||||||
add_queue(player->chunkRequests, cr);
|
queue_push(player->world->chunk_requests, request);
|
||||||
endProfilerSection("chunkLoading_live");
|
endProfilerSection("chunkLoading_live");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int32_t fz = last_chunk_z; last_chunk_z < chunk_z ? (fz < chunk_z) : (fz > chunk_z); last_chunk_z < chunk_z ? fz++ : fz--) {
|
for (int32_t fz = last_chunk_z; last_chunk_z < chunk_z ? (fz < chunk_z) : (fz > chunk_z); last_chunk_z < chunk_z ? fz++ : fz--) {
|
||||||
for (int32_t fx = last_chunk_x - CHUNK_VIEW_DISTANCE; fx <= last_chunk_x + CHUNK_VIEW_DISTANCE; fx++) {
|
for (int32_t fx = last_chunk_x - CHUNK_VIEW_DISTANCE; fx <= last_chunk_x + CHUNK_VIEW_DISTANCE; fx++) {
|
||||||
beginProfilerSection("chunkUnloading_live");
|
beginProfilerSection("chunkUnloading_live");
|
||||||
struct chunk_request* cr = xmalloc(sizeof(struct chunk_request));
|
struct chunk_request* request = pcalloc(player->world->chunk_request_pool, sizeof(struct chunk_request));
|
||||||
cr->chunk_x = fx;
|
request->chunk_x = fx;
|
||||||
cr->chunk_z = last_chunk_z < chunk_z ? (fz - CHUNK_VIEW_DISTANCE) : (fz + CHUNK_VIEW_DISTANCE);
|
request->chunk_z = last_chunk_z < chunk_z ? (fz - CHUNK_VIEW_DISTANCE) : (fz + CHUNK_VIEW_DISTANCE);
|
||||||
cr->load = 0;
|
request->load = 0;
|
||||||
add_queue(player->chunkRequests, cr);
|
queue_push(player->world->chunk_requests, request);
|
||||||
endProfilerSection("chunkUnloading_live");
|
endProfilerSection("chunkUnloading_live");
|
||||||
beginProfilerSection("chunkLoading_live");
|
beginProfilerSection("chunkLoading_live");
|
||||||
cr = xmalloc(sizeof(struct chunk_request));
|
request = pcalloc(player->world->chunk_request_pool, sizeof(struct chunk_request));
|
||||||
cr->chunk_x = fx;
|
request->chunk_x = fx;
|
||||||
cr->chunk_z = last_chunk_z < chunk_z ? (fz + CHUNK_VIEW_DISTANCE) : (fz - CHUNK_VIEW_DISTANCE);
|
request->chunk_z = last_chunk_z < chunk_z ? (fz + CHUNK_VIEW_DISTANCE) : (fz - CHUNK_VIEW_DISTANCE);
|
||||||
cr->load = 1;
|
request->load = 1;
|
||||||
cr->world = world;
|
request->world = player->world;
|
||||||
add_queue(player->chunkRequests, cr);
|
queue_push(player->world->chunk_requests, request);
|
||||||
endProfilerSection("chunkLoading_live");
|
endProfilerSection("chunkLoading_live");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&player->chunkRequests->data_mutex);
|
pthread_mutex_unlock(&player->world->chunk_requests->data_mutex);
|
||||||
pthread_cond_signal(&chunk_wake);
|
|
||||||
}
|
}
|
||||||
endProfilerSection("chunks");
|
endProfilerSection("chunks");
|
||||||
if (player->itemUseDuration > 0) {
|
if (player->itemUseDuration > 0) {
|
||||||
|
@ -297,29 +305,29 @@ void player_tick(struct player* player) {
|
||||||
player->entity->usingItemOff = 0;
|
player->entity->usingItemOff = 0;
|
||||||
updateMetadata(player->entity);
|
updateMetadata(player->entity);
|
||||||
} else if (ihi->maxUseDuration <= player->itemUseDuration) {
|
} else if (ihi->maxUseDuration <= player->itemUseDuration) {
|
||||||
if (ihi->onItemUse != NULL) (*ihi->onItemUse)(world, player, player->itemUseHand ? 45 : (36 + player->currentItem), ihs, player->itemUseDuration);
|
if (ihi->onItemUse != NULL) (*ihi->onItemUse)(player->world, player, (uint8_t) (player->itemUseHand ? 45 : (36 + player->currentItem)), ihs, player->itemUseDuration);
|
||||||
player->itemUseDuration = 0;
|
player->itemUseDuration = 0;
|
||||||
player->entity->usingItemMain = 0;
|
player->entity->usingItemMain = 0;
|
||||||
player->entity->usingItemOff = 0;
|
player->entity->usingItemOff = 0;
|
||||||
updateMetadata(player->entity);
|
updateMetadata(player->entity);
|
||||||
} else {
|
} else {
|
||||||
if (ihi->onItemUseTick != NULL) (*ihi->onItemUseTick)(world, player, player->itemUseHand ? 45 : (36 + player->currentItem), ihs, player->itemUseDuration);
|
if (ihi->onItemUseTick != NULL) (*ihi->onItemUseTick)(player->world, player, (uint8_t) (player->itemUseHand ? 45 : (36 + player->currentItem)), ihs, player->itemUseDuration);
|
||||||
player->itemUseDuration++;
|
player->itemUseDuration++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (((int32_t) player->entity->lx >> 4) != pcx || ((int32_t) player->entity->lz >> 4) != pcz || player->loaded_chunks->count < CHUNK_VIEW_DISTANCE * CHUNK_VIEW_DISTANCE * 4 || player->triggerRechunk) {
|
//if (((int32_t) player->entity->lx >> 4) != pcx || ((int32_t) player->entity->lz >> 4) != pcz || player->loaded_chunks->count < CHUNK_VIEW_DISTANCE * CHUNK_VIEW_DISTANCE * 4 || player->triggerRechunk) {
|
||||||
//}
|
//}
|
||||||
if (player->digging >= 0.) {
|
if (player->digging >= 0.) {
|
||||||
block bw = world_get_block(world, player->digging_position.x, player->digging_position.y, player->digging_position.z);
|
block bw = world_get_block(player->world, player->digging_position.x, player->digging_position.y, player->digging_position.z);
|
||||||
struct block_info* bi = getBlockInfo(bw);
|
struct block_info* bi = getBlockInfo(bw);
|
||||||
float digspeed = 0.;
|
float digspeed = 0.;
|
||||||
if (bi->hardness > 0.) {
|
if (bi->hardness > 0.) {
|
||||||
pthread_mutex_lock(&player->inventory->mut);
|
pthread_mutex_lock(&player->inventory->mutex);
|
||||||
struct slot* ci = inventory_get(player, player->inventory, 36 + player->currentItem);
|
struct slot* ci = inventory_get(player, player->inventory, 36 + player->currentItem);
|
||||||
struct item_info* cii = ci == NULL ? NULL : getItemInfo(ci->item);
|
struct item_info* cii = ci == NULL ? NULL : getItemInfo(ci->item);
|
||||||
int hasProperTool = (cii == NULL ? 0 : tools_proficient(cii->toolType, cii->harvestLevel, bw));
|
int hasProperTool = (cii == NULL ? 0 : tools_proficient(cii->toolType, cii->harvestLevel, bw));
|
||||||
int hasProperTool2 = (cii == NULL ? 0 : tools_proficient(cii->toolType, 0xFF, bw));
|
int hasProperTool2 = (cii == NULL ? 0 : tools_proficient(cii->toolType, 0xFF, bw));
|
||||||
pthread_mutex_unlock(&player->inventory->mut);
|
pthread_mutex_unlock(&player->inventory->mutex);
|
||||||
int rnt = bi->material->requiresnotool;
|
int rnt = bi->material->requiresnotool;
|
||||||
float ds = hasProperTool2 ? cii->toolProficiency : 1.;
|
float ds = hasProperTool2 ? cii->toolProficiency : 1.;
|
||||||
//efficiency enchantment
|
//efficiency enchantment
|
||||||
|
@ -342,52 +350,47 @@ void player_tick(struct player* player) {
|
||||||
}
|
}
|
||||||
player->digging += (player->digging == 0. ? 2. : 1.) * digspeed;
|
player->digging += (player->digging == 0. ? 2. : 1.) * digspeed;
|
||||||
BEGIN_BROADCAST_EXCEPT_DIST(player, player->entity, 128.)
|
BEGIN_BROADCAST_EXCEPT_DIST(player, player->entity, 128.)
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_BLOCKBREAKANIMATION);
|
||||||
pkt->id = PKT_PLAY_CLIENT_BLOCKBREAKANIMATION;
|
|
||||||
pkt->data.play_client.blockbreakanimation.entity_id = player->entity->id;
|
pkt->data.play_client.blockbreakanimation.entity_id = player->entity->id;
|
||||||
memcpy(&pkt->data.play_server.playerdigging.location, &player->digging_position, sizeof(struct encpos));
|
memcpy(&pkt->data.play_server.playerdigging.location, &player->digging_position, sizeof(struct encpos));
|
||||||
pkt->data.play_client.blockbreakanimation.destroy_stage = (int8_t) (player->digging * 9);
|
pkt->data.play_client.blockbreakanimation.destroy_stage = (int8_t) (player->digging * 9);
|
||||||
add_queue(bc_player->outgoing_packets, pkt);
|
queue_push(bc_player->outgoing_packets, pkt);
|
||||||
END_BROADCAST(player->world->players)
|
END_BROADCAST(player->world->players)
|
||||||
}
|
}
|
||||||
beginProfilerSection("entity_transmission");
|
beginProfilerSection("entity_transmission");
|
||||||
if (tick_counter % 20 == 0) {
|
if (player->world->tick_counter % 20 == 0) {
|
||||||
BEGIN_HASHMAP_ITERATION(player->loaded_entities)
|
pthread_rwlock_wrlock(&player->loaded_entities->rwlock);
|
||||||
struct entity* ent = (struct entity*) value;
|
ITER_MAP(player->loaded_entities)
|
||||||
if (entity_distsq(ent, player->entity) > (CHUNK_VIEW_DISTANCE * 16.) * (CHUNK_VIEW_DISTANCE * 16.)) {
|
{
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
struct entity* ent = (struct entity*) value;
|
||||||
pkt->id = PKT_PLAY_CLIENT_DESTROYENTITIES;
|
if (entity_distsq(ent, player->entity) > (CHUNK_VIEW_DISTANCE * 16.) * (CHUNK_VIEW_DISTANCE * 16.)) {
|
||||||
pkt->data.play_client.destroyentities.count = 1;
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_DESTROYENTITIES);
|
||||||
pkt->data.play_client.destroyentities.entity_ids = xmalloc(sizeof(int32_t));
|
pkt->data.play_client.destroyentities.count = 1;
|
||||||
pkt->data.play_client.destroyentities.entity_ids[0] = ent->id;
|
pkt->data.play_client.destroyentities.entity_ids = pmalloc(pkt->pool, sizeof(int32_t));
|
||||||
add_queue(player->outgoing_packets, pkt);
|
pkt->data.play_client.destroyentities.entity_ids[0] = ent->id;
|
||||||
put_hashmap(player->loaded_entities, ent->id, NULL);
|
queue_push(player->outgoing_packets, pkt);
|
||||||
put_hashmap(ent->loadingPlayers, player->entity->id, NULL);
|
hashmap_putint(player->loaded_entities, (uint64_t) ent->id, NULL);
|
||||||
|
hashmap_putint(ent->loadingPlayers, (uint64_t) player->entity->id, NULL);
|
||||||
|
}
|
||||||
|
ITER_MAP_END();
|
||||||
}
|
}
|
||||||
END_HASHMAP_ITERATION(player->loaded_entities)
|
pthread_rwlock_unlock(&player->loaded_entities->rwlock);
|
||||||
}
|
}
|
||||||
endProfilerSection("entity_transmission");
|
endProfilerSection("entity_transmission");
|
||||||
beginProfilerSection("player_transmission");
|
beginProfilerSection("player_transmission");
|
||||||
//int32_t chunk_x = ((int32_t) player->entity->x) >> 4;
|
ITER_MAP(player->world->entities) {
|
||||||
//int32_t chunk_z = ((int32_t) player->entity->z) >> 4;
|
struct entity* ent = (struct entity*) value;
|
||||||
//for (int32_t icx = chunk_x - CHUNK_VIEW_DISTANCE; icx <= chunk_x + CHUNK_VIEW_DISTANCE; icx++)
|
if (ent == player->entity || hashmap_getint(player->loaded_entities, (uint64_t) ent->id) || entity_distsq(player->entity, ent) > (CHUNK_VIEW_DISTANCE * 16.) * (CHUNK_VIEW_DISTANCE * 16.)) continue;
|
||||||
//for (int32_t icz = chunk_z - CHUNK_VIEW_DISTANCE; icz <= chunk_z + CHUNK_VIEW_DISTANCE; icz++) {
|
if (ent->type == ENT_PLAYER) loadPlayer(player, ent->data.player.player);
|
||||||
//struct chunk* ch = world_get_chunk(player->world, icx, icz);
|
else loadEntity(player, ent);
|
||||||
//if (ch != NULL) {
|
ITER_MAP_END();
|
||||||
BEGIN_HASHMAP_ITERATION(player->world->entities)
|
}
|
||||||
struct entity* ent = (struct entity*) value;
|
|
||||||
if (ent == player->entity || contains_hashmap(player->loaded_entities, ent->id) || entity_distsq(player->entity, ent) > (CHUNK_VIEW_DISTANCE * 16.) * (CHUNK_VIEW_DISTANCE * 16.)) continue;
|
|
||||||
if (ent->type == ENT_PLAYER) loadPlayer(player, ent->data.player.player);
|
|
||||||
else loadEntity(player, ent);
|
|
||||||
END_HASHMAP_ITERATION(player->world->entities)
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
endProfilerSection("player_transmission");
|
endProfilerSection("player_transmission");
|
||||||
BEGIN_HASHMAP_ITERATION(plugins)
|
ITER_MAP(plugins) {
|
||||||
struct plugin* plugin = value;
|
struct plugin* plugin = value;
|
||||||
if (plugin->tick_player != NULL) (*plugin->tick_player)(player->world, player);
|
if (plugin->tick_player != NULL) (*plugin->tick_player)(player->world, player);
|
||||||
END_HASHMAP_ITERATION(plugins)
|
ITER_MAP_END();
|
||||||
//printf("%i\n", player->loaded_chunks->size);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int player_onGround(struct player* player) {
|
int player_onGround(struct player* player) {
|
||||||
|
@ -436,18 +439,17 @@ int player_onGround(struct player* player) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void player_kick(struct player* player, char* message) {
|
void player_kick(struct player* player, char* message) {
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_DISCONNECT);
|
||||||
pkt->id = PKT_PLAY_CLIENT_DISCONNECT;
|
|
||||||
size_t sl = strlen(message);
|
size_t sl = strlen(message);
|
||||||
pkt->data.play_client.disconnect.reason = xmalloc(sl + 512);
|
pkt->data.play_client.disconnect.reason = pmalloc(pkt->pool, sl + 128);
|
||||||
snprintf(pkt->data.play_client.disconnect.reason, sl + 512, "{\"text\": \"%s\", \"color\": \"red\"}", message);
|
snprintf(pkt->data.play_client.disconnect.reason, sl + 128, "{\"text\": \"%s\", \"color\": \"red\"}", message);
|
||||||
add_queue(player->outgoing_packets, pkt);
|
queue_push(player->outgoing_packets, pkt);
|
||||||
if (player->conn != NULL) player->conn->disconnect = 1;
|
if (player->conn != NULL) player->conn->disconnect = 1;
|
||||||
broadcastf("red", "Kicked Player %s for reason: %s", player->name, message);
|
broadcastf("red", "Kicked Player %s for reason: %s", player->name, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
float player_getAttackStrength(struct player* player, float adjust) {
|
float player_getAttackStrength(struct player* player, float adjust) {
|
||||||
float cooldownPeriod = 4.;
|
float cooldownPeriod = 4f;
|
||||||
struct slot* sl = inventory_get(player, player->inventory, 36 + player->currentItem);
|
struct slot* sl = inventory_get(player, player->inventory, 36 + player->currentItem);
|
||||||
if (sl != NULL) {
|
if (sl != NULL) {
|
||||||
struct item_info* ii = getItemInfo(sl->item);
|
struct item_info* ii = getItemInfo(sl->item);
|
||||||
|
@ -455,9 +457,9 @@ float player_getAttackStrength(struct player* player, float adjust) {
|
||||||
cooldownPeriod = ii->attackSpeed;
|
cooldownPeriod = ii->attackSpeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float str = ((float) (tick_counter - player->lastSwing) + adjust) * cooldownPeriod / 20.;
|
float str = ((float) (player->world->tick_counter - player->lastSwing) + adjust) * cooldownPeriod / 20f;
|
||||||
if (str > 1.) str = 1.;
|
if (str > 1.) str = 1f;
|
||||||
if (str < 0.) str = 0.;
|
if (str < 0.) str = 0f;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,176 +470,126 @@ void player_teleport(struct player* player, double x, double y, double z) {
|
||||||
player->entity->last_x = x;
|
player->entity->last_x = x;
|
||||||
player->entity->last_y = y;
|
player->entity->last_y = y;
|
||||||
player->entity->last_z = z;
|
player->entity->last_z = z;
|
||||||
player->triggerRechunk = 1;
|
player->trigger_rechunk = 1;
|
||||||
player->spawnedIn = 0;
|
player->spawned_in = 0;
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_ENTITYVELOCITY);
|
||||||
pkt->id = PKT_PLAY_CLIENT_ENTITYVELOCITY;
|
|
||||||
pkt->data.play_client.entityvelocity.entity_id = player->entity->id;
|
pkt->data.play_client.entityvelocity.entity_id = player->entity->id;
|
||||||
pkt->data.play_client.entityvelocity.velocity_x = 0;
|
pkt->data.play_client.entityvelocity.velocity_x = 0;
|
||||||
pkt->data.play_client.entityvelocity.velocity_y = 0;
|
pkt->data.play_client.entityvelocity.velocity_y = 0;
|
||||||
pkt->data.play_client.entityvelocity.velocity_z = 0;
|
pkt->data.play_client.entityvelocity.velocity_z = 0;
|
||||||
add_queue(player->outgoing_packets, pkt);
|
queue_push(player->outgoing_packets, pkt);
|
||||||
pkt = xmalloc(sizeof(struct packet));
|
pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_PLAYERPOSITIONANDLOOK);
|
||||||
pkt->id = PKT_PLAY_CLIENT_PLAYERPOSITIONANDLOOK;
|
|
||||||
pkt->data.play_client.playerpositionandlook.x = player->entity->x;
|
pkt->data.play_client.playerpositionandlook.x = player->entity->x;
|
||||||
pkt->data.play_client.playerpositionandlook.y = player->entity->y;
|
pkt->data.play_client.playerpositionandlook.y = player->entity->y;
|
||||||
pkt->data.play_client.playerpositionandlook.z = player->entity->z;
|
pkt->data.play_client.playerpositionandlook.z = player->entity->z;
|
||||||
pkt->data.play_client.playerpositionandlook.yaw = player->entity->yaw;
|
pkt->data.play_client.playerpositionandlook.yaw = player->entity->yaw;
|
||||||
pkt->data.play_client.playerpositionandlook.pitch = player->entity->pitch;
|
pkt->data.play_client.playerpositionandlook.pitch = player->entity->pitch;
|
||||||
pkt->data.play_client.playerpositionandlook.flags = 0x0;
|
pkt->data.play_client.playerpositionandlook.flags = 0x0;
|
||||||
pkt->data.play_client.playerpositionandlook.teleport_id = tick_counter;
|
pkt->data.play_client.playerpositionandlook.teleport_id = (int32_t) player->world->tick_counter;
|
||||||
player->last_teleport_id = pkt->data.play_client.playerpositionandlook.teleport_id;
|
player->last_teleport_id = pkt->data.play_client.playerpositionandlook.teleport_id;
|
||||||
add_queue(player->outgoing_packets, pkt);
|
queue_push(player->outgoing_packets, pkt);
|
||||||
/*BEGIN_HASHMAP_ITERATION(player->entity->loadingPlayers)
|
|
||||||
struct player* bp = value;
|
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
|
||||||
pkt->id = PKT_PLAY_CLIENT_DESTROYENTITIES;
|
|
||||||
pkt->data.play_client.destroyentities.count = 1;
|
|
||||||
pkt->data.play_client.destroyentities.entity_ids = xmalloc(sizeof(int32_t));
|
|
||||||
pkt->data.play_client.destroyentities.entity_ids[0] = player->entity->id;
|
|
||||||
add_queue(bp->outgoing_packets, pkt);
|
|
||||||
put_hashmap(bp->loaded_entities, player->entity->id, NULL);
|
|
||||||
pthread_rwlock_unlock(&player->entity->loadingPlayers->data_mutex);
|
|
||||||
put_hashmap(player->entity->loadingPlayers, bp->entity->id, NULL);
|
|
||||||
pthread_rwlock_rdlock(&player->entity->loadingPlayers->data_mutex);
|
|
||||||
END_HASHMAP_ITERATION(player->entity->loadingPlayers)
|
|
||||||
BEGIN_HASHMAP_ITERATION(player->loaded_entities)
|
|
||||||
struct entity* be = value;
|
|
||||||
if (be->type != ENT_PLAYER) continue;
|
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
|
||||||
pkt->id = PKT_PLAY_CLIENT_DESTROYENTITIES;
|
|
||||||
pkt->data.play_client.destroyentities.count = 1;
|
|
||||||
pkt->data.play_client.destroyentities.entity_ids = xmalloc(sizeof(int32_t));
|
|
||||||
pkt->data.play_client.destroyentities.entity_ids[0] = be->id;
|
|
||||||
add_queue(player->outgoing_packets, pkt);
|
|
||||||
put_hashmap(player->loaded_entities, be->id, NULL);
|
|
||||||
put_hashmap(be->loadingPlayers, player->entity->id, NULL);
|
|
||||||
END_HASHMAP_ITERATION(player->loaded_entities)*/
|
|
||||||
// if (player->tps > 0) player->tps--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct player* player_get_by_name(char* name) {
|
struct player* player_get_by_name(struct server* server, char* name) {
|
||||||
BEGIN_HASHMAP_ITERATION(players)
|
//TODO: this should be a map lookup
|
||||||
struct player* player = (struct player*) value;
|
pthread_rwlock_rdlock(&server->players_by_entity_id->rwlock);
|
||||||
if (player != NULL && streq_nocase(name, player->name)) {
|
ITER_MAP (server->players_by_entity_id) {
|
||||||
BREAK_HASHMAP_ITERATION(players);
|
struct player* player = (struct player*) value;
|
||||||
return player;
|
if (player != NULL && str_eq(name, player->name)) {
|
||||||
|
pthread_rwlock_unlock(&server->players_by_entity_id->rwlock);
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
ITER_MAP_END();
|
||||||
}
|
}
|
||||||
END_HASHMAP_ITERATION(players)
|
pthread_rwlock_unlock(&server->players_by_entity_id->rwlock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void player_closeWindow(struct player* player, uint16_t windowID) {
|
void player_closeWindow(struct player* player, uint16_t windowID) {
|
||||||
struct inventory* inv = NULL;
|
struct inventory* inventory = NULL;
|
||||||
if (windowID == 0 && player->openInv == NULL) inv = player->inventory;
|
if (windowID == 0 && player->open_inventory == NULL) {
|
||||||
else if (player->open_inventory != NULL && windowID == player->open_inventory->windowID) inv = player->openInv;
|
inventory = player->inventory;
|
||||||
if (inv != NULL) {
|
} else if (player->open_inventory != NULL && windowID == player->open_inventory->window) {
|
||||||
pthread_mutex_lock(&inv->mut);
|
inventory = player->open_inventory;
|
||||||
if (player->inHand != NULL) {
|
}
|
||||||
dropPlayerItem(player, player->inHand);
|
if (inventory != NULL) {
|
||||||
freeSlot(player->inHand);
|
pthread_mutex_lock(&inventory->mutex);
|
||||||
xfree(player->inHand);
|
if (player->inventory_holding != NULL) {
|
||||||
player->inHand = NULL;
|
dropPlayerItem(player, player->inventory_holding);
|
||||||
|
player->inventory_holding = NULL;
|
||||||
}
|
}
|
||||||
if (inv->type == INVTYPE_PLAYERINVENTORY) {
|
if (inventory->type == INVTYPE_PLAYERINVENTORY) {
|
||||||
for (int i = 1; i < 5; i++) {
|
for (int i = 1; i < 5; i++) {
|
||||||
if (inv->slots[i] != NULL) {
|
if (inventory->slots[i] != NULL) {
|
||||||
dropPlayerItem(player, inv->slots[i]);
|
dropPlayerItem(player, inventory->slots[i]);
|
||||||
inventory_set_slot(player, inv, i, NULL, 0, 1);
|
inventory_set_slot(player, inventory, i, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (inv->type == INVTYPE_WORKBENCH) {
|
} else if (inventory->type == INVTYPE_WORKBENCH) {
|
||||||
for (int i = 1; i < 10; i++) {
|
for (int i = 1; i < 10; i++) {
|
||||||
if (inv->slots[i] != NULL) {
|
if (inventory->slots[i] != NULL) {
|
||||||
dropPlayerItem(player, inv->slots[i]);
|
dropPlayerItem(player, inventory->slots[i]);
|
||||||
inventory_set_slot(player, inv, i, NULL, 0, 1);
|
inventory_set_slot(player, inventory, i, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&inv->mut);
|
pthread_mutex_unlock(&inventory->mutex);
|
||||||
freeInventory(inv);
|
pfree(inventory->pool);
|
||||||
inv = NULL;
|
inventory = NULL;
|
||||||
} else if (inv->type == INVTYPE_CHEST) {
|
} else if (inventory->type == INVTYPE_CHEST) {
|
||||||
if (inv->tile != NULL) {
|
if (inventory->tile != NULL) {
|
||||||
BEGIN_BROADCAST_DIST(player->entity, 128.)
|
BEGIN_BROADCAST_DIST(player->entity, 128.){
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_BLOCKACTION);
|
||||||
pkt->id = PKT_PLAY_CLIENT_BLOCKACTION;
|
pkt->data.play_client.blockaction.location.x = inventory->tile->x;
|
||||||
pkt->data.play_client.blockaction.location.x = inv->tile->x;
|
pkt->data.play_client.blockaction.location.y = inventory->tile->y;
|
||||||
pkt->data.play_client.blockaction.location.y = inv->tile->y;
|
pkt->data.play_client.blockaction.location.z = inventory->tile->z;
|
||||||
pkt->data.play_client.blockaction.location.z = inv->tile->z;
|
pkt->data.play_client.blockaction.action_id = 1;
|
||||||
pkt->data.play_client.blockaction.action_id = 1;
|
pkt->data.play_client.blockaction.action_param = (uint8_t) (inventory->watching_players->entry_count - 1);
|
||||||
pkt->data.play_client.blockaction.action_param = inv->players->entry_count - 1;
|
pkt->data.play_client.blockaction.block_type = world_get_block(player->world, inventory->tile->x, inventory->tile->y, inventory->tile->z) >> 4;
|
||||||
pkt->data.play_client.blockaction.block_type = world_get_block(player->world, inv->tile->x, inv->tile->y, inv->tile->z) >> 4;
|
queue_push(bc_player->outgoing_packets, pkt);
|
||||||
add_queue(bc_player->outgoing_packets, pkt);
|
END_BROADCAST(player->entity->world->players)
|
||||||
END_BROADCAST(player->world->players)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (inv != NULL) {
|
if (inventory != NULL) {
|
||||||
if (inv->type != INVTYPE_PLAYERINVENTORY) put_hashmap(inv->players, player->entity->id, NULL);
|
if (inventory->type != INVTYPE_PLAYERINVENTORY) {
|
||||||
pthread_mutex_unlock(&inv->mut);
|
hashmap_putint(inventory->watching_players, (uint64_t) player->entity->id, NULL);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&inventory->mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
player->openInv = NULL; // TODO: free sometimes?
|
player->open_inventory = NULL; // TODO: free sometimes?
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void player_set_gamemode(struct player* player, int gamemode) {
|
void player_set_gamemode(struct player* player, int gamemode) {
|
||||||
if (gamemode != -1) {
|
if (gamemode != -1) {
|
||||||
player->gamemode = gamemode;
|
player->gamemode = (uint8_t) gamemode;
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_CHANGEGAMESTATE);
|
||||||
pkt->id = PKT_PLAY_CLIENT_CHANGEGAMESTATE;
|
pkt->id = PKT_PLAY_CLIENT_CHANGEGAMESTATE;
|
||||||
pkt->data.play_client.changegamestate.reason = 3;
|
pkt->data.play_client.changegamestate.reason = 3;
|
||||||
pkt->data.play_client.changegamestate.value = gamemode;
|
pkt->data.play_client.changegamestate.value = gamemode;
|
||||||
add_queue(player->outgoing_packets, pkt);
|
queue_push(player->outgoing_packets, pkt);
|
||||||
}
|
}
|
||||||
struct packet* pkt = xmalloc(sizeof(struct packet));
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_PLAYERABILITIES);
|
||||||
pkt->id = PKT_PLAY_CLIENT_PLAYERABILITIES;
|
pkt->data.play_client.playerabilities.flags = (int8_t) (player->gamemode == 1 ? (0x04 | 0x08) : 0x0);
|
||||||
pkt->data.play_client.playerabilities.flags = player->gamemode == 1 ? (0x04 | 0x08) : 0x0;
|
|
||||||
pkt->data.play_client.playerabilities.flying_speed = .05;
|
pkt->data.play_client.playerabilities.flying_speed = .05;
|
||||||
pkt->data.play_client.playerabilities.field_of_view_modifier = .1;
|
pkt->data.play_client.playerabilities.field_of_view_modifier = .1;
|
||||||
add_queue(player->outgoing_packets, pkt);
|
queue_push(player->outgoing_packets, pkt);
|
||||||
}
|
|
||||||
|
|
||||||
void player_free(struct player* player) {
|
|
||||||
struct packet* pkt = NULL;
|
|
||||||
while ((pkt = pop_nowait_queue(player->incoming_packets)) != NULL) {
|
|
||||||
freePacket(STATE_PLAY, 0, pkt);
|
|
||||||
xfree(pkt);
|
|
||||||
}
|
|
||||||
del_queue(player->incoming_packets);
|
|
||||||
while ((pkt = pop_nowait_queue(player->outgoing_packets)) != NULL) {
|
|
||||||
freePacket(STATE_PLAY, 1, pkt);
|
|
||||||
xfree(pkt);
|
|
||||||
}
|
|
||||||
del_queue(player->outgoing_packets);
|
|
||||||
struct chunk_request* cr;
|
|
||||||
while ((cr = pop_nowait_queue(player->chunkRequests)) != NULL) {
|
|
||||||
xfree(cr);
|
|
||||||
}
|
|
||||||
del_queue(player->chunkRequests);
|
|
||||||
if (player->inHand != NULL) {
|
|
||||||
freeSlot(player->inHand);
|
|
||||||
xfree(player->inHand);
|
|
||||||
}
|
|
||||||
del_hashmap(player->loaded_chunks);
|
|
||||||
del_hashmap(player->loaded_entities);
|
|
||||||
freeInventory(player->inventory);
|
|
||||||
xfree(player->inventory);
|
|
||||||
xfree(player->name);
|
|
||||||
xfree(player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block player_can_place_block(struct player* player, block blk, int32_t x, int32_t y, int32_t z, uint8_t face) {
|
block player_can_place_block(struct player* player, block blk, int32_t x, int32_t y, int32_t z, uint8_t face) {
|
||||||
struct block_info* bi = getBlockInfo(blk);
|
struct block_info* info = getBlockInfo(blk);
|
||||||
block tbb = blk;
|
block blk_updated = blk;
|
||||||
if (bi != NULL && bi->onBlockPlacedPlayer != NULL) tbb = (*bi->onBlockPlacedPlayer)(player, player->world, tbb, x, y, z, face);
|
if (info != NULL && info->onBlockPlacedPlayer != NULL) blk_updated = (*info->onBlockPlacedPlayer)(player, player->world, blk_updated, x, y, z, face);
|
||||||
BEGIN_HASHMAP_ITERATION(plugins)
|
ITER_MAP(plugins) {
|
||||||
struct plugin* plugin = value;
|
struct plugin* plugin = value;
|
||||||
if (plugin->onBlockPlacedPlayer != NULL) tbb = (*plugin->onBlockPlacedPlayer)(player, player->world, tbb, x, y, z, face);
|
if (plugin->onBlockPlacedPlayer != NULL) blk_updated = (*plugin->onBlockPlacedPlayer)(player, player->world, blk_updated, x, y, z, face);
|
||||||
END_HASHMAP_ITERATION(plugins)
|
ITER_MAP_END();
|
||||||
bi = getBlockInfo(blk);
|
}
|
||||||
if (bi != NULL && bi->canBePlaced != NULL && !(*bi->canBePlaced)(player->world, tbb, x, y, z)) {
|
info = getBlockInfo(blk);
|
||||||
|
if (info != NULL && info->canBePlaced != NULL && !(*info->canBePlaced)(player->world, blk_updated, x, y, z)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
block b = world_get_block(player->world, x, y, z);
|
block new_block = world_get_block(player->world, x, y, z);
|
||||||
return (b == 0 || getBlockInfo(b)->material->replacable) ? tbb : 0;
|
return (block) ((new_block == 0 || getBlockInfo(new_block)->material->replacable) ? blk_updated : 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -599,12 +599,12 @@ void player_packet_handle_useentity(struct player* player, struct mempool* pool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (packet->type == 1) {
|
} else if (packet->type == 1) {
|
||||||
if (entity != NULL && entity != player->entity && entity->health > 0. && entity->world == player->world && entity_dist(entity, player->entity) < 4. && (player->server->tick_counter - player->lastSwing) >= 3) {
|
if (entity != NULL && entity != player->entity && entity->health > 0. && entity->world == player->world && entity_dist(entity, player->entity) < 4. && (player->world->tick_counter - player->lastSwing) >= 3) {
|
||||||
pthread_mutex_lock(&player->inventory->mutex);
|
pthread_mutex_lock(&player->inventory->mutex);
|
||||||
damageEntityWithItem(entity, player->entity, (uint8_t) (36 + player->currentItem), inventory_get(player, player->inventory, 36 + player->currentItem));
|
damageEntityWithItem(entity, player->entity, (uint8_t) (36 + player->currentItem), inventory_get(player, player->inventory, 36 + player->currentItem));
|
||||||
pthread_mutex_unlock(&player->inventory->mutex);
|
pthread_mutex_unlock(&player->inventory->mutex);
|
||||||
}
|
}
|
||||||
player->lastSwing = player->server->tick_counter;
|
player->lastSwing = player->world->tick_counter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,7 +926,7 @@ void player_packet_handle_updatesign(struct player* player, struct mempool* pool
|
||||||
}
|
}
|
||||||
|
|
||||||
void player_packet_handle_animation(struct player* player, struct mempool* pool, struct pkt_play_server_animation* packet) {
|
void player_packet_handle_animation(struct player* player, struct mempool* pool, struct pkt_play_server_animation* packet) {
|
||||||
player->lastSwing = player->server->tick_counter;
|
player->lastSwing = player->world->tick_counter;
|
||||||
BEGIN_BROADCAST_EXCEPT_DIST(player, player->entity, CHUNK_VIEW_DISTANCE * 16.){
|
BEGIN_BROADCAST_EXCEPT_DIST(player, player->entity, CHUNK_VIEW_DISTANCE * 16.){
|
||||||
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_ANIMATION);
|
struct packet* pkt = packet_new(mempool_new(), PKT_PLAY_CLIENT_ANIMATION);
|
||||||
pkt->data.play_client.animation.entity_id = player->entity->id;
|
pkt->data.play_client.animation.entity_id = player->entity->id;
|
||||||
|
|
11
src/world.c
11
src/world.c
|
@ -162,7 +162,7 @@ void world_chunkload_thread(struct world* world) {
|
||||||
world_unload_chunk(request->world, chunk);
|
world_unload_chunk(request->world, chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pprefree(world->pool, request);
|
pprefree(world->chunk_request_pool, request);
|
||||||
/*
|
/*
|
||||||
BEGIN_HASHMAP_ITERATION (players)
|
BEGIN_HASHMAP_ITERATION (players)
|
||||||
struct player* player = value;
|
struct player* player = value;
|
||||||
|
@ -779,7 +779,9 @@ struct world* world_new(struct server* server) {
|
||||||
world->ticksInSecond = 0;
|
world->ticksInSecond = 0;
|
||||||
world->seed = 9876543;
|
world->seed = 9876543;
|
||||||
perlin_init(&world->perlin, world->seed);
|
perlin_init(&world->perlin, world->seed);
|
||||||
world->chunk_requests = queue_new(0, 1, world->pool);
|
world->chunk_request_pool = mempool_new();
|
||||||
|
pchild(world->pool, world->chunk_request_pool);
|
||||||
|
world->chunk_requests = queue_new(0, 1, world->chunk_request_pool);
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,11 +862,12 @@ void world_tick(struct world* world) {
|
||||||
pthread_cond_wait(&world->tick_cond, &world->tick_mut);
|
pthread_cond_wait(&world->tick_cond, &world->tick_mut);
|
||||||
pthread_mutex_unlock(&world->tick_mut);
|
pthread_mutex_unlock(&world->tick_mut);
|
||||||
beginProfilerSection("world_tick");
|
beginProfilerSection("world_tick");
|
||||||
if (tick_counter % 20 == 0) {
|
if (world->tick_counter % 20 == 0) {
|
||||||
world->tps = world->ticksInSecond;
|
world->tps = world->ticksInSecond;
|
||||||
world->ticksInSecond = 0;
|
world->ticksInSecond = 0;
|
||||||
}
|
}
|
||||||
world->ticksInSecond++;
|
++world->tick_counter;
|
||||||
|
++world->ticksInSecond;
|
||||||
world_pretick(world);
|
world_pretick(world);
|
||||||
beginProfilerSection("player_receive_packet");
|
beginProfilerSection("player_receive_packet");
|
||||||
pthread_rwlock_rdlock(&world->players->rwlock);
|
pthread_rwlock_rdlock(&world->players->rwlock);
|
||||||
|
|
Loading…
Reference in New Issue