forked from EXTERNAL/bareiron
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_interact (int client_fd);
|
||||||
int cs_playerInput (int client_fd);
|
int cs_playerInput (int client_fd);
|
||||||
int cs_playerCommand (int client_fd);
|
int cs_playerCommand (int client_fd);
|
||||||
|
int cs_playerLoaded (int client_fd);
|
||||||
|
|
||||||
// Clientbound packets
|
// Clientbound packets
|
||||||
int sc_statusResponse (int client_fd);
|
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 reservePlayerData (int client_fd, uint8_t *uuid, char* name);
|
||||||
int getPlayerData (int client_fd, PlayerData **output);
|
int getPlayerData (int client_fd, PlayerData **output);
|
||||||
void handlePlayerDisconnect (int client_fd);
|
void handlePlayerDisconnect (int client_fd);
|
||||||
|
void handlePlayerJoin (PlayerData* player);
|
||||||
void disconnectClient (int *client_fd, int cause);
|
void disconnectClient (int *client_fd, int cause);
|
||||||
int givePlayerItem (PlayerData *player, uint16_t item, uint8_t count);
|
int givePlayerItem (PlayerData *player, uint16_t item, uint8_t count);
|
||||||
void spawnPlayer (PlayerData *player);
|
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
|
// Send full client spawn sequence
|
||||||
spawnPlayer(player);
|
spawnPlayer(player);
|
||||||
|
|
||||||
// Prepare join message for broadcast
|
// Register all existing players and spawn their entities
|
||||||
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.
|
|
||||||
for (int i = 0; i < MAX_PLAYERS; i ++) {
|
for (int i = 0; i < MAX_PLAYERS; i ++) {
|
||||||
if (player_data[i].client_fd == -1) continue;
|
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_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(client_fd, player_data[i]);
|
||||||
sc_spawnEntityPlayer(player_data[i].client_fd, *player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send information about all other entities (mobs)
|
// 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);
|
if (state == STATE_PLAY) cs_playerInput(client_fd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2B: { // Player Loaded
|
case 0x2B:
|
||||||
PlayerData *player;
|
if (state == STATE_PLAY) cs_playerLoaded(client_fd);
|
||||||
if (getPlayerData(client_fd, &player)) break;
|
|
||||||
// Clear "client loading" flag and fallback timer
|
|
||||||
player->flags &= ~0x20;
|
|
||||||
player->flagval_16 = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case 0x34:
|
case 0x34:
|
||||||
if (state == STATE_PLAY) cs_setHeldItem(client_fd);
|
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;
|
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)
|
// S->C Registry Data (multiple packets) and Update Tags (configuration, multiple packets)
|
||||||
int sc_registries (int client_fd) {
|
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) {
|
void disconnectClient (int *client_fd, int cause) {
|
||||||
if (*client_fd == -1) return;
|
if (*client_fd == -1) return;
|
||||||
client_count --;
|
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
|
// If 3 seconds (60 vanilla ticks) have passed, assume player has loaded
|
||||||
player->flagval_16 ++;
|
player->flagval_16 ++;
|
||||||
if (player->flagval_16 > (uint16_t)(3 * TICKS_PER_SECOND)) {
|
if (player->flagval_16 > (uint16_t)(3 * TICKS_PER_SECOND)) {
|
||||||
player->flags &= ~0x20;
|
handlePlayerJoin(player);
|
||||||
player->flagval_16 = 0;
|
|
||||||
} else continue;
|
} else continue;
|
||||||
}
|
}
|
||||||
// Reset player attack cooldown
|
// Reset player attack cooldown
|
||||||
|
Reference in New Issue
Block a user