1
0
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:
p2r3
2025-09-13 20:06:25 +03:00
parent bad337a032
commit e3589a02f0
5 changed files with 43 additions and 21 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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