mirror of
https://github.com/p2r3/bareiron.git
synced 2025-10-01 23:25:09 +02:00
fix player entities desyncing on join sometimes
This commit is contained in:
@@ -21,6 +21,7 @@ int cs_chat (int client_fd);
|
||||
int cs_interact (int client_fd);
|
||||
int cs_playerInput (int client_fd);
|
||||
int cs_playerCommand (int client_fd);
|
||||
int cs_playerLoaded (int client_fd);
|
||||
|
||||
// Clientbound packets
|
||||
int sc_statusResponse (int client_fd);
|
||||
|
@@ -15,6 +15,7 @@ void resetPlayerData (PlayerData *player);
|
||||
int reservePlayerData (int client_fd, uint8_t *uuid, char* name);
|
||||
int getPlayerData (int client_fd, PlayerData **output);
|
||||
void handlePlayerDisconnect (int client_fd);
|
||||
void handlePlayerJoin (PlayerData* player);
|
||||
void disconnectClient (int *client_fd, int cause);
|
||||
int givePlayerItem (PlayerData *player, uint16_t item, uint8_t count);
|
||||
void spawnPlayer (PlayerData *player);
|
||||
|
24
src/main.c
24
src/main.c
@@ -126,22 +126,13 @@ void handlePacket (int client_fd, int length, int packet_id, int state) {
|
||||
// Send full client spawn sequence
|
||||
spawnPlayer(player);
|
||||
|
||||
// Prepare join message for broadcast
|
||||
uint8_t player_name_len = strlen(player->name);
|
||||
strcpy((char *)recv_buffer, player->name);
|
||||
strcpy((char *)recv_buffer + player_name_len, " joined the game");
|
||||
|
||||
// Register all existing players and spawn their entities, and broadcast
|
||||
// information about the joining player to all existing players.
|
||||
// Register all existing players and spawn their entities
|
||||
for (int i = 0; i < MAX_PLAYERS; i ++) {
|
||||
if (player_data[i].client_fd == -1) continue;
|
||||
if (player_data[i].flags & 0x20 && player_data[i].client_fd != client_fd) continue;
|
||||
// Note that this will also filter out the joining player
|
||||
if (player_data[i].flags & 0x20) continue;
|
||||
sc_playerInfoUpdateAddPlayer(client_fd, player_data[i]);
|
||||
sc_systemChat(player_data[i].client_fd, (char *)recv_buffer, 16 + player_name_len);
|
||||
if (player_data[i].client_fd == client_fd) continue;
|
||||
sc_playerInfoUpdateAddPlayer(player_data[i].client_fd, *player);
|
||||
sc_spawnEntityPlayer(client_fd, player_data[i]);
|
||||
sc_spawnEntityPlayer(player_data[i].client_fd, *player);
|
||||
}
|
||||
|
||||
// Send information about all other entities (mobs)
|
||||
@@ -431,14 +422,9 @@ void handlePacket (int client_fd, int length, int packet_id, int state) {
|
||||
if (state == STATE_PLAY) cs_playerInput(client_fd);
|
||||
break;
|
||||
|
||||
case 0x2B: { // Player Loaded
|
||||
PlayerData *player;
|
||||
if (getPlayerData(client_fd, &player)) break;
|
||||
// Clear "client loading" flag and fallback timer
|
||||
player->flags &= ~0x20;
|
||||
player->flagval_16 = 0;
|
||||
case 0x2B:
|
||||
if (state == STATE_PLAY) cs_playerLoaded(client_fd);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x34:
|
||||
if (state == STATE_PLAY) cs_setHeldItem(client_fd);
|
||||
|
@@ -1178,6 +1178,18 @@ int sc_pickupItem (int client_fd, int collected, int collector, uint8_t count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// C->S Player Loaded
|
||||
int cs_playerLoaded (int client_fd) {
|
||||
|
||||
PlayerData *player;
|
||||
if (getPlayerData(client_fd, &player)) return 1;
|
||||
|
||||
// Redirect handling to player join procedure
|
||||
handlePlayerJoin(player);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// S->C Registry Data (multiple packets) and Update Tags (configuration, multiple packets)
|
||||
int sc_registries (int client_fd) {
|
||||
|
||||
|
@@ -146,6 +146,29 @@ void handlePlayerDisconnect (int client_fd) {
|
||||
}
|
||||
}
|
||||
|
||||
// Marks a client as connected and broadcasts their data to other players
|
||||
void handlePlayerJoin (PlayerData* player) {
|
||||
|
||||
// Prepare join message for broadcast
|
||||
uint8_t player_name_len = strlen(player->name);
|
||||
strcpy((char *)recv_buffer, player->name);
|
||||
strcpy((char *)recv_buffer + player_name_len, " joined the game");
|
||||
|
||||
// Inform other clients (and the joining client) of the player's name and entity
|
||||
for (int i = 0; i < MAX_PLAYERS; i ++) {
|
||||
sc_systemChat(player_data[i].client_fd, (char *)recv_buffer, 16 + player_name_len);
|
||||
sc_playerInfoUpdateAddPlayer(player_data[i].client_fd, *player);
|
||||
if (player_data[i].client_fd != player->client_fd) {
|
||||
sc_spawnEntityPlayer(player_data[i].client_fd, *player);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear "client loading" flag and fallback timer
|
||||
player->flags &= ~0x20;
|
||||
player->flagval_16 = 0;
|
||||
|
||||
}
|
||||
|
||||
void disconnectClient (int *client_fd, int cause) {
|
||||
if (*client_fd == -1) return;
|
||||
client_count --;
|
||||
@@ -1414,8 +1437,7 @@ void handleServerTick (int64_t time_since_last_tick) {
|
||||
// If 3 seconds (60 vanilla ticks) have passed, assume player has loaded
|
||||
player->flagval_16 ++;
|
||||
if (player->flagval_16 > (uint16_t)(3 * TICKS_PER_SECOND)) {
|
||||
player->flags &= ~0x20;
|
||||
player->flagval_16 = 0;
|
||||
handlePlayerJoin(player);
|
||||
} else continue;
|
||||
}
|
||||
// Reset player attack cooldown
|
||||
|
Reference in New Issue
Block a user