private int TryReadPacket()
        {
            MemoryStream ms = new MemoryStream(received.ToArray());
            if (received.Count == 0)
            {
                return 0;
            }
            int packetLength;
            int lengthPrefixLength;
            bool packetLengthOk = Serializer.TryReadLengthPrefix(ms, PrefixStyle.Base128, out packetLength);
            lengthPrefixLength = (int)ms.Position;
            if (!packetLengthOk || lengthPrefixLength + packetLength > ms.Length)
            {
                return 0;
            }
            ms.Position = 0;
            PacketServer packet = Serializer.DeserializeWithLengthPrefix<PacketServer>(ms, PrefixStyle.Base128);
            if (Debugger.IsAttached
                && packet.PacketId != ServerPacketId.PositionUpdate
                && packet.PacketId != ServerPacketId.OrientationUpdate
                && packet.PacketId != ServerPacketId.PlayerPositionAndOrientation
                && packet.PacketId != ServerPacketId.ExtendedPacketTick
                && packet.PacketId != ServerPacketId.Chunk
                && packet.PacketId != ServerPacketId.Ping)
            {
                Console.WriteLine(Enum.GetName(typeof(MinecraftServerPacketId), packet.PacketId));
            }
            switch (packet.PacketId)
            {
                case ServerPacketId.ServerIdentification:
                    {
                        string invalidversionstr = "Invalid game version. Local: {0}, Server: {1}. Do you want to connect anyway?";
                        {
                            string servergameversion = packet.Identification.MdProtocolVersion;
                            if (servergameversion != GameVersion.Version)
                            {
                                for (int i = 0; i < 5; i++)
                                {
                                    System.Windows.Forms.Cursor.Show();
                                    System.Threading.Thread.Sleep(100);
                                    Application.DoEvents();
                                }
                                string q = string.Format(invalidversionstr, GameVersion.Version, servergameversion);
                                var result = System.Windows.Forms.MessageBox.Show(q, "Invalid version", System.Windows.Forms.MessageBoxButtons.OKCancel);
                                if (result == System.Windows.Forms.DialogResult.Cancel)
                                {
                                    throw new Exception(q);
                                }
                                for (int i = 0; i < 10; i++)
                                {
                                    System.Windows.Forms.Cursor.Hide();
                                    System.Threading.Thread.Sleep(100);
                                    Application.DoEvents();
                                }
                            }
                        }
                        this.serverName = packet.Identification.ServerName;
                        this.ServerMotd = packet.Identification.ServerMotd;
                        this.AllowFreemove = !packet.Identification.DisallowFreemove;
                        ChatLog("---Connected---");
                        List<byte[]> needed = new List<byte[]>();
                        foreach (byte[] b in packet.Identification.UsedBlobsMd5)
                        {
                            if (!IsBlob(b)) { needed.Add(b); }
                        }
                        SendRequestBlob(needed);
                        if (packet.Identification.MapSizeX != d_Map.MapSizeX
                            || packet.Identification.MapSizeY != d_Map.MapSizeY
                            || packet.Identification.MapSizeZ != d_Map.MapSizeZ)
                        {
                            d_ResetMap.Reset(packet.Identification.MapSizeX,
                                packet.Identification.MapSizeY,
                                packet.Identification.MapSizeZ);
                        }
                    }
                    break;
                case ServerPacketId.Ping:
                    {
                    }
                    break;
                case ServerPacketId.LevelInitialize:
                    {
                        ReceivedMapLength = 0;
                        InvokeMapLoadingProgress(0, 0, "Connecting...");
                    }
                    break;
                case ServerPacketId.LevelDataChunk:
                    {
                        MapLoadingPercentComplete = packet.LevelDataChunk.PercentComplete;
                        MapLoadingStatus = packet.LevelDataChunk.Status;
                        InvokeMapLoadingProgress(MapLoadingPercentComplete, (int)ReceivedMapLength, MapLoadingStatus);
                    }
                    break;
                case ServerPacketId.LevelFinalize:
                    {
                        d_Data.Load(MyStream.ReadAllLines(d_GetFile.GetFile("blocks.csv")),
                            MyStream.ReadAllLines(d_GetFile.GetFile("defaultmaterialslots.csv")),
                            MyStream.ReadAllLines(d_GetFile.GetFile("lightlevels.csv")));
                        d_CraftingRecipes.Load(MyStream.ReadAllLines(d_GetFile.GetFile("craftingrecipes.csv")));

                        if (MapLoaded != null)
                        {
                            MapLoaded.Invoke(this, new MapLoadedEventArgs() { });
                        }
                        loadedtime = DateTime.Now;
                    }
                    break;
                case ServerPacketId.SetBlock:
                    {
                        int x = packet.SetBlock.X;
                        int y = packet.SetBlock.Y;
                        int z = packet.SetBlock.Z;
                        int type = packet.SetBlock.BlockType;
                        try { SetTileAndUpdate(new Vector3(x, y, z), type); }
                        catch { Console.WriteLine("Cannot update tile!"); }
                    }
                    break;
                case ServerPacketId.SpawnPlayer:
                    {
                        int playerid = packet.SpawnPlayer.PlayerId;
                        string playername = packet.SpawnPlayer.PlayerName;
                        connectedplayers.Add(new ConnectedPlayer() { name = playername, id = playerid });
                        d_Clients.Players[playerid] = new Player();
                        d_Clients.Players[playerid].Name = playername;
                        ReadAndUpdatePlayerPosition(packet.SpawnPlayer.PositionAndOrientation, playerid);
                        if (playerid == 255)
                        {
                            spawned = true;
                        }
                    }
                    break;
                case ServerPacketId.PlayerPositionAndOrientation:
                    {
                        int playerid = packet.PositionAndOrientation.PlayerId;
                        ReadAndUpdatePlayerPosition(packet.PositionAndOrientation.PositionAndOrientation, playerid);
                    }
                    break;
                case ServerPacketId.Monster:
                    {
                        if (packet.Monster.Monsters == null)
                        {
                            break;
                        }
                        Dictionary<int, int> updatedMonsters = new Dictionary<int, int>();
                        foreach (var k in packet.Monster.Monsters)
                        {
                            int id = k.Id + MonsterIdFirst;
                            if (!players.ContainsKey(id))
                            {
                                players[id] = new Player()
                                {
                                    Name = d_DataMonsters.MonsterName[k.MonsterType],
                                };
                            }
                            ReadAndUpdatePlayerPosition(k.PositionAndOrientation, id);
                            players[id].Type = PlayerType.Monster;
                            players[id].Health = k.Health;
                            players[id].MonsterType = k.MonsterType;
                            updatedMonsters[id] = 1;
                        }
                        //remove all old monsters that were not sent by server now.
                        foreach (int id in new List<int>(players.Keys))
                        {
                            if (id >= MonsterIdFirst)
                            {
                                if (!updatedMonsters.ContainsKey(id))
                                {
                                    players.Remove(id);
                                }
                            }
                        }
                    }
                    break;
                case ServerPacketId.DespawnPlayer:
                    {
                        int playerid = packet.DespawnPlayer.PlayerId;
                        for (int i = 0; i < connectedplayers.Count; i++)
                        {
                            if (connectedplayers[i].id == playerid)
                            {
                                connectedplayers.RemoveAt(i);
                            }
                        }
                        d_Clients.Players.Remove(playerid);
                    }
                    break;
                case ServerPacketId.Message:
                    {
                        AddChatline(packet.Message.Message);
                        ChatLog(packet.Message.Message);
                    }
                    break;
                case ServerPacketId.DisconnectPlayer:
                    {
                        throw new Exception(packet.DisconnectPlayer.DisconnectReason);
                    }
                case ServerPacketId.Chunk:
                    {
                        var p = packet.Chunk;
                        if (p.CompressedChunk != null)
                        {
                            byte[] decompressedchunk = d_Compression.Decompress(p.CompressedChunk);
                            byte[, ,] receivedchunk = new byte[p.SizeX, p.SizeY, p.SizeZ];
                            {
                                BinaryReader br2 = new BinaryReader(new MemoryStream(decompressedchunk));
                                for (int zz = 0; zz < p.SizeZ; zz++)
                                {
                                    for (int yy = 0; yy < p.SizeY; yy++)
                                    {
                                        for (int xx = 0; xx < p.SizeX; xx++)
                                        {
                                            receivedchunk[xx, yy, zz] = br2.ReadByte();
                                        }
                                    }
                                }
                            }
                            d_Map.SetMapPortion(p.X, p.Y, p.Z, receivedchunk);
                            for (int xx = 0; xx < 2; xx++)
                            {
                                for (int yy = 0; yy < 2; yy++)
                                {
                                    for (int zz = 0; zz < 2; zz++)
                                    {
                                        d_Shadows.OnSetChunk(p.X + 16 * xx, p.Y + 16 * yy, p.Z + 16 * zz);//todo
                                    }
                                }
                            }

                        }
                        ReceivedMapLength += lengthPrefixLength + packetLength;
                    }
                    break;
                case ServerPacketId.HeightmapChunk:
                    {
                        var p = packet.HeightmapChunk;
                        byte[] decompressedchunk = d_Compression.Decompress(p.CompressedHeightmap);
                        for (int xx = 0; xx < p.SizeX; xx++)
                        {
                            for (int yy = 0; yy < p.SizeY; yy++)
                            {
                                int height = decompressedchunk[MapUtil.Index2d(xx, yy, p.SizeX)];
                                d_Heightmap.SetBlock(p.X + xx, p.Y + yy, height);
                            }
                        }
                    }
                    break;
                case ServerPacketId.PlayerStats:
                    {
                        var p = packet.PlayerStats;
                        this.PlayerStats = p;
                    }
                    break;
                default:
                    break;
            }
            {
                bool handled = NetworkPacketReceived(packet);
                if (!handled)
                {
                    //Console.WriteLine("Invalid packet id: " + packet.PacketId);
                }
            }
            LastReceived = currentTime;
            return lengthPrefixLength + packetLength;
        }