Beispiel #1
0
        private byte[] Compress(ICollection <Packet> packets)
        {
            long length = 0;

            foreach (Packet packet in packets)
            {
                length += packet.Encode().Length;
            }

            var compressionLevel = _session.CompressionThreshold > -1 && length >= _session.CompressionThreshold ?
                                   System.IO.Compression.CompressionLevel.Fastest : System.IO.Compression.CompressionLevel.NoCompression;

            using (MemoryStream stream = MiNetServer.MemoryStreamManager.GetStream())
            {
                int checksum;

                using (var compressStream = new DeflateStream(stream, compressionLevel, true))
                {
                    foreach (Packet packet in packets)
                    {
                        byte[] bs = packet.Encode();

                        if (bs != null && bs.Length > 0)
                        {
                            BatchUtils.WriteLength(compressStream, bs.Length);
                            compressStream.Write(bs, 0, bs.Length);
                        }

                        packet.PutPool();
                    }

                    compressStream.Flush();
                }

                byte[] bytes = stream.ToArray();

                return(bytes);
            }
        }
Beispiel #2
0
        private void SendQueue()
        {
            if (_sendQueueNotConcurrent.Count == 0)
            {
                return;
            }

            if (!Monitor.TryEnter(_syncHack))
            {
                return;
            }

            try
            {
                using (MemoryStream memStream = MiNetServer.MemoryStreamManager.GetStream())
                {
                    Queue <Package> queue = _sendQueueNotConcurrent;

                    int messageCount = 0;

                    int lenght = queue.Count;
                    for (int i = 0; i < lenght; i++)
                    {
                        Package package = null;
                        lock (_queueSync)
                        {
                            if (queue.Count == 0)
                            {
                                break;
                            }
                            try
                            {
                                package = queue.Dequeue();
                            }
                            catch (Exception e)
                            {
                            }
                        }

                        if (package == null)
                        {
                            continue;
                        }

                        if (State == ConnectionState.Unconnected)
                        {
                            package.PutPool();
                            continue;
                        }

                        if (lenght == 1)
                        {
                            Server.SendPackage(this, package);
                        }
                        else if (package is McpeWrapper)
                        {
                            SendBuffered(messageCount, memStream);
                            messageCount = 0;
                            Server.SendPackage(this, package);
                            Thread.Sleep(1);                             // Really important to slow down speed a bit
                        }
                        else if (package.NoBatch)
                        {
                            SendBuffered(messageCount, memStream);
                            messageCount = 0;
                            Server.SendPackage(this, package);
                        }
                        else
                        {
                            if (messageCount == 0)
                            {
                                memStream.Position = 0;
                                memStream.SetLength(0);
                            }

                            byte[] bytes = package.Encode();
                            if (bytes != null)
                            {
                                messageCount++;
                                BatchUtils.WriteLength(memStream, bytes.Length);
                                //memStream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                                memStream.Write(bytes, 0, bytes.Length);
                            }

                            package.PutPool();
                        }
                    }

                    if (State == ConnectionState.Unconnected)
                    {
                        return;
                    }

                    SendBuffered(messageCount, memStream);
                }
            }
            finally
            {
                Monitor.Exit(_syncHack);
            }
        }
Beispiel #3
0
        protected virtual void BroadCastMovement(Player[] players, Entity[] entities)
        {
            DateTime now = DateTime.UtcNow;

            if (players.Length == 0)
            {
                return;
            }

            if (players.Length <= 1 && entities.Length == 0)
            {
                return;
            }

            if (now - _lastBroadcast < TimeSpan.FromMilliseconds(50))
            {
                return;
            }

            DateTime tickTime = _lastSendTime;

            _lastSendTime = DateTime.UtcNow;

            using (MemoryStream stream = MiNetServer.MemoryStreamManager.GetStream())
            {
                int playerMoveCount = 0;
                int entiyMoveCount  = 0;

                foreach (var player in players)
                {
                    if (now - player.LastUpdatedTime <= now - tickTime)
                    {
                        PlayerLocation knownPosition = player.KnownPosition;

                        McpeMovePlayer move = McpeMovePlayer.CreateObject();
                        move.entityId = player.EntityId;
                        move.x        = knownPosition.X;
                        move.y        = knownPosition.Y + 1.62f;
                        move.z        = knownPosition.Z;
                        move.yaw      = knownPosition.Yaw;
                        move.pitch    = knownPosition.Pitch;
                        move.headYaw  = knownPosition.HeadYaw;
                        move.mode     = 0;
                        byte[] bytes = move.Encode();
                        BatchUtils.WriteLength(stream, bytes.Length);
                        stream.Write(bytes, 0, bytes.Length);
                        move.PutPool();
                        playerMoveCount++;
                    }
                }

                foreach (var entity in entities)
                {
                    if (now - entity.LastUpdatedTime <= now - tickTime)
                    {
                        {
                            McpeMoveEntity moveEntity = McpeMoveEntity.CreateObject();
                            moveEntity.entityId    = entity.EntityId;
                            moveEntity.position    = (PlayerLocation)entity.KnownPosition.Clone();
                            moveEntity.position.Y += entity.PositionOffset;
                            byte[] bytes = moveEntity.Encode();
                            BatchUtils.WriteLength(stream, bytes.Length);
                            stream.Write(bytes, 0, bytes.Length);
                            moveEntity.PutPool();
                        }
                        {
                            McpeSetEntityMotion entityMotion = McpeSetEntityMotion.CreateObject();
                            entityMotion.entityId = entity.EntityId;
                            entityMotion.velocity = entity.Velocity;
                            byte[] bytes = entityMotion.Encode();
                            BatchUtils.WriteLength(stream, bytes.Length);
                            stream.Write(bytes, 0, bytes.Length);
                            entityMotion.PutPool();
                        }
                        entiyMoveCount++;
                    }
                }

                if (playerMoveCount == 0 && entiyMoveCount == 0)
                {
                    return;
                }

                if (players.Length == 1 && entiyMoveCount == 0)
                {
                    return;
                }

                McpeBatch batch = BatchUtils.CreateBatchPacket(stream.GetBuffer(), 0, (int)stream.Length, CompressionLevel.Optimal, false);
                batch.AddReferences(players.Length - 1);
                batch.Encode();
                //batch.ValidUntil = now + TimeSpan.FromMilliseconds(50);
                foreach (var player in players)
                {
                    MiNetServer.FastThreadPool.QueueUserWorkItem(() => player.SendPackage(batch));
                }
                _lastBroadcast = DateTime.UtcNow;
            }
        }
Beispiel #4
0
        public void SendQueue()
        {
            if (_sendQueueNotConcurrent.Count == 0)
            {
                return;
            }

            if (!Monitor.TryEnter(_syncHack))
            {
                return;
            }

            try
            {
                using (MemoryStream memStream = new MemoryStream())
                {
                    Queue <Packet> queue = _sendQueueNotConcurrent;

                    int messageCount = 0;

                    int lenght = queue.Count;
                    for (int i = 0; i < lenght; i++)
                    {
                        Packet packet = null;
                        lock (_queueSync)
                        {
                            if (queue.Count == 0)
                            {
                                break;
                            }
                            try
                            {
                                packet = queue.Dequeue();
                            }
                            catch (Exception e)
                            {
                            }
                        }

                        if (packet == null)
                        {
                            continue;
                        }

                        if (State == ConnectionState.Unconnected)
                        {
                            packet.PutPool();
                            continue;
                        }

                        if (lenght == 1)
                        {
                            Server.SendPacket(this, packet);
                        }
                        else if (packet is McpeWrapper)
                        {
                            SendBuffered(messageCount, memStream);
                            messageCount = 0;
                            Server.SendPacket(this, packet);
                            // The following is necessary if no throttling is done on chunk sending,
                            // but having it creates a lot of packet lag when using SpawnLevel. You can see it
                            // as players standing still, but having running particles.
                            //
                            //Thread.Sleep(1); // Really important to slow down speed a bit
                        }
                        else if (packet.NoBatch)
                        {
                            SendBuffered(messageCount, memStream);
                            messageCount = 0;
                            Server.SendPacket(this, packet);
                        }
                        else
                        {
                            if (messageCount == 0)
                            {
                                memStream.Position = 0;
                                memStream.SetLength(0);
                            }

                            byte[] bytes = packet.Encode();
                            if (bytes != null)
                            {
                                messageCount++;
                                BatchUtils.WriteLength(memStream, bytes.Length);
                                //memStream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                                memStream.Write(bytes, 0, bytes.Length);
                            }

                            packet.PutPool();
                        }
                    }

                    if (State == ConnectionState.Unconnected)
                    {
                        return;
                    }

                    SendBuffered(messageCount, memStream);
                }
            }
            finally
            {
                Monitor.Exit(_syncHack);
            }
        }