protected virtual void OnDesyncDetected(DesyncEventArgs e) { PrepareEvent(e); #if DEBUG _chat.AddMessage("Desync detected, fixing..."); #endif logger.Info("Desync detected, fixing..."); foreach (var chunkPos in e.ChunksToSynchronize) { _chunks.ResyncChunk(chunkPos, true); } foreach (var entityId in e.EntitiesToSynchronize) { _server.ServerConnection.Send(new GetEntityMessage { DynamicEntityId = entityId }); } var handler = DesyncDetected; if (handler != null) { handler(this, e); } }
private void PrepareEvent(DesyncEventArgs e) { if (e.ChunksToSynchronize == null) { e.ChunksToSynchronize = new List <Vector3I>(); } if (e.EntitiesToSynchronize == null) { e.EntitiesToSynchronize = new List <uint>(); } // we will resync our entity only if the source entity is close enough if (!e.EntitiesToSynchronize.Contains(PlayerManager.PlayerCharacter.DynamicId)) { if (e.EntitiesToSynchronize.Count > 0) { var entity = _dynamicEntityManager.GetEntityById(e.EntitiesToSynchronize[0]); if (Vector3D.DistanceSquared(entity.Position, PlayerManager.PlayerCharacter.Position) < 1024) // (16*2)^2 = 1024 (2 chunks range) { e.EntitiesToSynchronize.Add(PlayerManager.PlayerCharacter.DynamicId); } } else { e.EntitiesToSynchronize.Add(PlayerManager.PlayerCharacter.DynamicId); } } // find chunks to resync foreach (var entityId in e.EntitiesToSynchronize) { var entity = entityId == PlayerManager.PlayerCharacter.DynamicId ? PlayerManager.PlayerCharacter : _dynamicEntityManager.FindEntity(new EntityLink(entityId)); if (entity != null) { var rootPos = BlockHelper.EntityToChunkPosition(entity.Position); e.ChunksToSynchronize.Add(rootPos); for (int x = -1; x < 2; x++) { for (int z = -1; z < 2; z++) { if (x == 0 && z == 0) { continue; } e.ChunksToSynchronize.Add(rootPos + new Vector3I(x, 0, z)); } } } } e.ChunksToSynchronize = e.ChunksToSynchronize.Distinct().ToList(); }