Example #1
0
        internal void SendChunks(object state)
        {
            MapChunkBulkPacket packet = new MapChunkBulkPacket();

            for (int i = 0; i < 20 && !ChunksToBeSent.IsEmpty; ++i)
            {
                Chunk chunk;
                ChunksToBeSent.TryDequeue(out chunk);

                packet.ChunksToSend.Add(chunk);
            }

            SendPacket(packet);

            if (ChunksToBeSent.IsEmpty)
            {
                _chunkSendTimer.Change(Timeout.Infinite, Timeout.Infinite);
                Interlocked.Exchange(ref _chunkTimerRunning, 0);
            }

            if (!ChunksToBeSent.IsEmpty)
            {
                int running = Interlocked.Exchange(ref _chunkTimerRunning, 1);

                if (running == 0)
                {
                    if (_lastChunkTimerStart != DateTime.MinValue)
                    {
                        _startDelay = 1000 - (int)(DateTime.Now - _lastChunkTimerStart).TotalMilliseconds;
                    }

                    if (_startDelay < 0)
                    {
                        _startDelay = 0;
                    }
                    _chunkSendTimer.Change(_startDelay, 1000);
                }
            }
            _lastChunkTimerStart = DateTime.Now;
        }
Example #2
0
        public void UpdateChunks(int radius, CancellationToken token, bool sync, bool remove)
        {
            int chunkX = (int)(Math.Floor(Position.X)) >> 4;
            int chunkZ = (int)(Math.Floor(Position.Z)) >> 4;

            Dictionary <int, int> nearbyChunks = new Dictionary <int, int>();

            MapChunkBulkPacket chunkPacket = null;

            if (sync)
            {
                chunkPacket = new MapChunkBulkPacket();
            }

            for (int x = chunkX - radius; x <= chunkX + radius; ++x)
            {
                for (int z = chunkZ - radius; z <= chunkZ + radius; ++z)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }

                    int packedChunk = UniversalCoords.FromChunkToPackedChunk(x, z);

                    nearbyChunks.Add(packedChunk, packedChunk);

                    if (!LoadedChunks.ContainsKey(packedChunk))
                    {
                        Chunk chunk;
                        if (sync)
                        {
                            chunk = World.GetChunkFromChunkSync(x, z, true, true) as Chunk;
                        }
                        else
                        {
                            chunk = World.GetChunkFromChunkAsync(x, z, Client, true, true) as Chunk;
                        }

                        LoadedChunks.TryAdd(packedChunk, chunk);

                        if (chunk == null)
                        {
                            continue;
                        }

                        if (chunk.LightToRecalculate)
                        {
#if PROFILE
                            Stopwatch watch = new Stopwatch();
                            watch.Start();

                            chunk.RecalculateSky();

                            watch.Stop();

                            World.Logger.Log(LogLevel.Info, "Skylight recalc: {0}", watch.ElapsedMilliseconds);
#else
                            chunk.RecalculateSky();
#endif
                        }

                        chunk.AddClient(Client);
                        if (!sync)
                        {
                            _client.SendChunk(chunk);
                        }
                        else
                        {
                            chunkPacket.ChunksToSend.Add(chunk);
                        }
                    }
                }
            }

            if (sync)
            {
                _client.Send_Sync_Packet(chunkPacket);
            }

            if (remove)
            {
                foreach (int c in LoadedChunks.Keys.Where(c => !nearbyChunks.ContainsKey(c)))
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    Chunk chunk;
                    LoadedChunks.TryRemove(c, out chunk);


                    if (chunk != null)
                    {
                        chunk.RemoveClient(_client);
                    }
                }
            }
        }