Example #1
0
        void UpdatePlayerVisibleChunks(PlayerChunkLoadState state)
        {
            if (state.Entity == null)
            {
                return;
            }
            state.ChunksToUnload.Clear();

            _tempVisList.Clear();
            var centerPos = ChunkHelper.GetChunkIdFromCoords(state.Entity.Position);

            var dim = (WorldOptions.MaxLoadRadius - 1) * 2;

            ChunkHelper.Spiral(dim, dim, (x, y) => { _tempVisList.Add(centerPos.Add(x, 0, y)); });
            foreach (var c in _tempVisList)
            {
                if (state.SentChunks.Contains(c) || state.SendQueue.Contains(c) || state.LoadGenQueue.Contains(c))
                {
                    continue;
                }
                state.LoadGenQueue.Enqueue(c);
            }

            var maxLoadDistance = WorldOptions.ChunkUnloadDistance * WorldOptions.ChunkUnloadDistance;

            foreach (var c in state.SentChunks)
            {
                var dist = Int3.SquareDistanceFlat(centerPos, c);
                if (dist > maxLoadDistance)
                {
                    state.ChunksToUnload.Add(c);
                }
            }
        }
Example #2
0
 void UnloadChunkOnClient(PlayerChunkLoadState state, Int3 index)
 {
     state.SentChunks.Remove(index);
     ServerController.Instance.SendNetMessage(state.Client, ServerPacketID.ChunkUnload, new S_UnloadChunkMessage()
     {
         X = index.X, Y = index.Y, Z = index.Z
     });
 }
Example #3
0
        void UpdateClientQueues(PlayerChunkLoadState state)
        {
            while (state.LoadGenQueue.Count > 0)
            {
                var c = state.LoadGenQueue.Dequeue();
                state.SendQueue.Enqueue(c);

                var chunk = GetChunk(c);
                if (!_usedChunks.ContainsKey(c))
                {
                    _usedChunks.Add(c, 1);
                }
                else
                {
                    _usedChunks[c] += 1;
                }

                if (chunk == null)
                {
                    GenOrLoad(c.X, c.Z, true);
                    break;
                }
            }

            if (state.SendQueue.Count > 0)
            {
                var c     = state.SendQueue.Dequeue();
                var chunk = GetChunk(c);
                if (chunk != null)
                {
                    SendChunkToClient(state, chunk.GetData(), c);
                }
                else
                {
                    state.SendQueue.Enqueue(c);
                }
            }

            if (state.ChunksToUnload.Count > 0)
            {
                foreach (var item in state.ChunksToUnload)
                {
                    UnloadChunkOnClient(state, item);
                    _usedChunks[item] -= 1;
                    if (_usedChunks[item] <= 0)
                    {
                        _usedChunks.Remove(item);
                    }
                }
                state.ChunksToUnload.Clear();
            }

            if (state.SendQueue.Count == 0 && !state.PlayerInited)
            {
                state.PlayerInited = true;
                FinalizeClientWorldInitialization(state.Client);
            }
        }
Example #4
0
        void CreateInitialSendQueue(PlayerChunkLoadState state)
        {
            Vector3 spawnPoint  = ServerPlayerEntityManager.Instance.GetLastSavedPosition(state.Client);
            var     centerChunk = ChunkHelper.GetChunkIdFromCoords(spawnPoint);

            var queue = state.LoadGenQueue;

            var dim = (WorldOptions.ChunkLoadRadius - 1) * 2;

            ChunkHelper.Spiral(dim, dim, (x, z) => {
                queue.Enqueue(centerChunk.Add(x, 0, z));
            });
        }
Example #5
0
        void SendChunkToClient(PlayerChunkLoadState state, ChunkData data, Int3 index)
        {
            state.SentChunks.Add(index);
            var blockCount = (data.Height + 1) * 16 * 16;

            using (var str = new MemoryStream(_chunkSendBuffer)) {
                using (var writer = new BinaryWriter(str)) {
                    var count = ChunkSerializer.Serialize(data, writer, true);
                    var dst   = new byte[count];
                    System.Array.Copy(_chunkSendBuffer, dst, count);
                    ServerController.Instance.SendRawNetMessage(state.Client, ServerPacketID.ChunkInit, dst, false);
                }
            }
        }
Example #6
0
        void OnPlayerJoin(OnClientConnected e)
        {
            DebugOutput.LogFormat("Player {0} joined. Starting to send world info.", e.State.UserName);

            var state = new PlayerChunkLoadState()
            {
                Client       = e.State,
                PlayerInited = false
            };

            _playerStates.Add(e.State, state);

            CreateInitialSendQueue(state);
            var wsc = ServerWorldStateController.Instance;             //TODO: Move to world state controller

            wsc.SendToClient(e.State);
        }