Ejemplo n.º 1
0
        private int TryReadPacket()
        {
            BinaryReader br = new BinaryReader(new MemoryStream(received.ToArray()));
            if (received.Count == 0)
            {
                return 0;
            }
            var packetId = (MinecraftServerPacketId)br.ReadByte();
            int totalread = 1;
            if (packetId != MinecraftServerPacketId.PositionandOrientationUpdate
                 && packetId != MinecraftServerPacketId.PositionUpdate
                && packetId != MinecraftServerPacketId.OrientationUpdate
                && packetId != MinecraftServerPacketId.PlayerTeleport
                && packetId != MinecraftServerPacketId.ExtendedPacketTick)
            {
                Console.WriteLine(Enum.GetName(typeof(MinecraftServerPacketId), packetId));
            }
            switch (packetId)
            {
                case MinecraftServerPacketId.ServerIdentification:
                    {
                        totalread += 1 + NetworkHelper.StringLength + NetworkHelper.StringLength + 1; if (received.Count < totalread) { return 0; }
                        if (ENABLE_FORTRESS)
                        {
                            totalread += NetworkHelper.StringLength; if (received.Count < totalread) { return 0; }
                        }
                        ServerPlayerIdentification p = new ServerPlayerIdentification();
                        p.ProtocolVersion = br.ReadByte();
                        string invalidversionstr = "Invalid game version. Local: {0}, Server: {1}";
                        if (!ENABLE_FORTRESS)
                        {
                            if (!(p.ProtocolVersion == 7 || p.ProtocolVersion == 6))
                            {
                                throw new Exception(string.Format(invalidversionstr,
                                    "Minecraft 7", "Minecraft " + p.ProtocolVersion));
                            }
                        }
                        else
                        {
                            string servergameversion = NetworkHelper.ReadString64(br);
                            if (p.ProtocolVersion != 200)
                            {
                                servergameversion = "Minecraft " + p.ProtocolVersion;
                            }
                            if (servergameversion != GameVersion.Version)
                            {
                                throw new Exception(string.Format(invalidversionstr, GameVersion.Version, servergameversion));
                            }
                        }
                        p.ServerName = NetworkHelper.ReadString64(br);
                        p.ServerMotd = NetworkHelper.ReadString64(br);
                        p.UserType = br.ReadByte();
                        //connected = true;
                        this.serverName = p.ServerName;
                        this.ServerMotd = p.ServerMotd;
                        ChatLog("---Connected---");
                    }
                    break;
                case MinecraftServerPacketId.Ping:
                    {
                    }
                    break;
                case MinecraftServerPacketId.LevelInitialize:
                    {
                        receivedMapStream = new MemoryStream();
                        InvokeMapLoadingProgress(0, 0);
                    }
                    break;
                case MinecraftServerPacketId.LevelDataChunk:
                    {
                        totalread += 2 + 1024 + 1; if (received.Count < totalread) { return 0; }
                        int chunkLength = NetworkHelper.ReadInt16(br);
                        byte[] chunkData = br.ReadBytes(1024);
                        BinaryWriter bw1 = new BinaryWriter(receivedMapStream);
                        byte[] chunkDataWithoutPadding = new byte[chunkLength];
                        for (int i = 0; i < chunkLength; i++)
                        {
                            chunkDataWithoutPadding[i] = chunkData[i];
                        }
                        bw1.Write(chunkDataWithoutPadding);
                        MapLoadingPercentComplete = br.ReadByte();
                        InvokeMapLoadingProgress(MapLoadingPercentComplete, (int)receivedMapStream.Length);
                    }
                    break;
                case MinecraftServerPacketId.LevelFinalize:
                    {
                        totalread += 2 + 2 + 2; if (received.Count < totalread) { return 0; }
                        if (ENABLE_FORTRESS)
                        {
                            totalread += 4; if (received.Count < totalread) { return 0; } //simulationstartframe
                        }
                        mapreceivedsizex = NetworkHelper.ReadInt16(br);
                        mapreceivedsizez = NetworkHelper.ReadInt16(br);
                        mapreceivedsizey = NetworkHelper.ReadInt16(br);
                        receivedMapStream.Seek(0, SeekOrigin.Begin);
                        if (!ENABLE_FORTRESS)
                        {
                            MemoryStream decompressed = new MemoryStream(compression.Decompress(receivedMapStream.ToArray()));
                            if (decompressed.Length != mapreceivedsizex * mapreceivedsizey * mapreceivedsizez +
                                (decompressed.Length % 1024))
                            {
                                //throw new Exception();
                                Console.WriteLine("warning: invalid map data size");
                            }
                            byte[, ,] receivedmap = new byte[mapreceivedsizex, mapreceivedsizey, mapreceivedsizez];
                            {
                                BinaryReader br2 = new BinaryReader(decompressed);
                                int size = NetworkHelper.ReadInt32(br2);
                                for (int z = 0; z < mapreceivedsizez; z++)
                                {
                                    for (int y = 0; y < mapreceivedsizey; y++)
                                    {
                                        for (int x = 0; x < mapreceivedsizex; x++)
                                        {
                                            receivedmap[x, y, z] = br2.ReadByte();
                                        }
                                    }
                                }
                            }
                            MapStoragePortion.UseMap(receivedmap);
                            Map.Map.MapSizeX = receivedmap.GetUpperBound(0) + 1;
                            Map.Map.MapSizeY = receivedmap.GetUpperBound(1) + 1;
                            Map.Map.MapSizeZ = receivedmap.GetUpperBound(2) + 1;
                            Console.WriteLine("Game loaded successfully.");
                        }
                        else
                        {
                            int simulationstartframe = NetworkHelper.ReadInt32(br);
                            gameworld.LoadState(receivedMapStream.ToArray(), simulationstartframe);
                        }
                        if (MapLoaded != null)
                        {
                            MapLoaded.Invoke(this, new MapLoadedEventArgs() { });
                        }
                        loadedtime = DateTime.Now;
                    }
                    break;
                case MinecraftServerPacketId.SetBlock:
                    {
                        int x;
                        int y;
                        int z;
                        if (ENABLE_FORTRESS)
                        {
                            throw new Exception("SetBlock packet");//no such packet.
                        }
                        else
                        {
                            totalread += 2 + 2 + 2 + 1; if (received.Count < totalread) { return 0; }
                            x = NetworkHelper.ReadInt16(br);
                            z = NetworkHelper.ReadInt16(br);
                            y = NetworkHelper.ReadInt16(br);
                        }
                        byte type = br.ReadByte();
                        try { Map.SetTileAndUpdate(new Vector3(x, y, z), type); }
                        catch { Console.WriteLine("Cannot update tile!"); }
                    }
                    break;
                case MinecraftServerPacketId.SpawnPlayer:
                    {
                        if (ENABLE_FORTRESS)
                        {
                            totalread += 1 + NetworkHelper.StringLength + 4 + 4 + 4 + 1 + 1; if (received.Count < totalread) { return 0; }
                        }
                        else
                        {
                            totalread += 1 + NetworkHelper.StringLength + 2 + 2 + 2 + 1 + 1; if (received.Count < totalread) { return 0; }
                        }
                        byte playerid = br.ReadByte();
                        string playername = NetworkHelper.ReadString64(br);
                        if (ENABLE_FORTRESS && playerid == 255)
                        {
                            spawned = true;
                            break;
                        }
                        connectedplayers.Add(new ConnectedPlayer() { name = playername, id = playerid });
                        if (Clients.Players.ContainsKey(playerid))
                        {
                            //throw new Exception();
                        }
                        Clients.Players[playerid] = new Player();
                        Clients.Players[playerid].Name = playername;
                        if (ENABLE_FORTRESS && ((DateTime.Now - loadedtime).TotalSeconds > 10))
                        {
                            ReadAndUpdatePlayerPosition(br, playerid);
                        }
                        if (!ENABLE_FORTRESS)
                        {
                            ReadAndUpdatePlayerPosition(br, playerid);
                        }
                        if (playerid == 255)
                        {
                            spawned = true;
                        }
                    }
                    break;
                case MinecraftServerPacketId.PlayerTeleport:
                    {
                        if (ENABLE_FORTRESS)
                        {
                            totalread += 1 + (4 + 4 + 4) + 1 + 1; if (received.Count < totalread) { return 0; }
                        }
                        else
                        {
                            totalread += 1 + (2 + 2 + 2) + 1 + 1; if (received.Count < totalread) { return 0; }
                        }
                        byte playerid = br.ReadByte();
                        ReadAndUpdatePlayerPosition(br, playerid);
                    }
                    break;
                case MinecraftServerPacketId.PositionandOrientationUpdate:
                    {
                        totalread += 1 + (1 + 1 + 1) + 1 + 1; if (received.Count < totalread) { return 0; }
                        byte playerid = br.ReadByte();
                        float x = (float)br.ReadSByte() / 32;
                        float y = (float)br.ReadSByte() / 32;
                        float z = (float)br.ReadSByte() / 32;
                        byte heading = br.ReadByte();
                        byte pitch = br.ReadByte();
                        Vector3 v = new Vector3(x, y, z);
                        UpdatePositionDiff(playerid, v);
                    }
                    break;
                case MinecraftServerPacketId.PositionUpdate:
                    {
                        totalread += 1 + 1 + 1 + 1; if (received.Count < totalread) { return 0; }
                        byte playerid = br.ReadByte();
                        float x = (float)br.ReadSByte() / 32;
                        float y = (float)br.ReadSByte() / 32;
                        float z = (float)br.ReadSByte() / 32;
                        Vector3 v = new Vector3(x, y, z);
                        UpdatePositionDiff(playerid, v);
                    }
                    break;
                case MinecraftServerPacketId.OrientationUpdate:
                    {
                        totalread += 1 + 1 + 1; if (received.Count < totalread) { return 0; }
                        byte playerid = br.ReadByte();
                        byte heading = br.ReadByte();
                        byte pitch = br.ReadByte();
                        Clients.Players[playerid].Heading = heading;
                        Clients.Players[playerid].Pitch = pitch;
                    }
                    break;
                case MinecraftServerPacketId.DespawnPlayer:
                    {
                        totalread += 1; if (received.Count < totalread) { return 0; }
                        byte playerid = br.ReadByte();
                        for (int i = 0; i < connectedplayers.Count; i++)
                        {
                            if (connectedplayers[i].id == playerid)
                            {
                                connectedplayers.RemoveAt(i);
                            }
                        }
                        Clients.Players.Remove(playerid);
                    }
                    break;
                case MinecraftServerPacketId.Message:
                    {
                        totalread += 1 + NetworkHelper.StringLength; if (received.Count < totalread) { return 0; }
                        byte unused = br.ReadByte();
                        string message = NetworkHelper.ReadString64(br);
                        Chatlines.AddChatline(message);
                        ChatLog(message);
                    }
                    break;
                case MinecraftServerPacketId.DisconnectPlayer:
                    {
                        totalread += NetworkHelper.StringLength; if (received.Count < totalread) { return 0; }
                        string disconnectReason = NetworkHelper.ReadString64(br);
                        throw new Exception(disconnectReason);
                    }
                case MinecraftServerPacketId.ExtendedPacketCommand:
                    {
                        totalread += 1 + 4 + 4; if (received.Count < totalread) { return 0; }
                        int playerid = br.ReadByte();
                        int cmdframe = NetworkHelper.ReadInt32(br);
                        int length = NetworkHelper.ReadInt32(br);
                        totalread += length; if (received.Count < totalread) { return 0; }
                        byte[] cmd = br.ReadBytes(length);
                        gameworld.EnqueueCommand(playerid, cmdframe, cmd);
                    }
                    break;
                case MinecraftServerPacketId.ExtendedPacketTick:
                    {
                        totalread += 4 + 4; if (received.Count < totalread) { return 0; }
                        int allowedframe = NetworkHelper.ReadInt32(br);
                        int hash = NetworkHelper.ReadInt32(br);

                        totalread += 1; if (received.Count < totalread) { return 0; }
                        int clientscount = br.ReadByte();
                        totalread += clientscount * (1 + (3 * 4) + 1 + 1); if (received.Count < totalread) { return 0; }
                        Dictionary<int, PlayerPosition> playerpositions = new Dictionary<int, PlayerPosition>();
                        for (int i = 0; i < clientscount; i++)
                        {
                            byte playerid = br.ReadByte();
                            //copied
                            float x = (float)((double)NetworkHelper.ReadInt32(br) / 32);
                            float y = (float)((double)NetworkHelper.ReadInt32(br) / 32);
                            float z = (float)((double)NetworkHelper.ReadInt32(br) / 32);
                            byte heading = br.ReadByte();
                            byte pitch = br.ReadByte();
                            playerpositions[playerid] = new PlayerPosition() { position = new Vector3(x, y, z), heading = heading, pitch = pitch };
                        }
                        gameworld.KeyFrame(allowedframe, hash, playerpositions);
                    }
                    break;
                default:
                    {
                        throw new Exception("Invalid packet id");
                    }
            }
            return totalread;
        }
Ejemplo n.º 2
0
        private int TryReadPacket()
        {
            BinaryReader br = new BinaryReader(new MemoryStream(received.ToArray()));

            if (received.Count == 0)
            {
                return(0);
            }
            var packetId  = (MinecraftServerPacketId)br.ReadByte();
            int totalread = 1;

            if (packetId != MinecraftServerPacketId.PositionandOrientationUpdate &&
                packetId != MinecraftServerPacketId.PositionUpdate &&
                packetId != MinecraftServerPacketId.OrientationUpdate &&
                packetId != MinecraftServerPacketId.PlayerTeleport &&
                packetId != MinecraftServerPacketId.ExtendedPacketTick)
            {
                Console.WriteLine(Enum.GetName(typeof(MinecraftServerPacketId), packetId));
            }
            switch (packetId)
            {
            case MinecraftServerPacketId.ServerIdentification:
            {
                totalread += 1 + NetworkHelper.StringLength + NetworkHelper.StringLength + 1; if (received.Count < totalread)
                {
                    return(0);
                }
                if (ENABLE_FORTRESS)
                {
                    totalread += NetworkHelper.StringLength; if (received.Count < totalread)
                    {
                        return(0);
                    }
                }
                ServerPlayerIdentification p = new ServerPlayerIdentification();
                p.ProtocolVersion = br.ReadByte();
                string invalidversionstr = "Invalid game version. Local: {0}, Server: {1}";
                if (!ENABLE_FORTRESS)
                {
                    if (!(p.ProtocolVersion == 7 || p.ProtocolVersion == 6))
                    {
                        throw new Exception(string.Format(invalidversionstr,
                                                          "Minecraft 7", "Minecraft " + p.ProtocolVersion));
                    }
                }
                else
                {
                    string servergameversion = NetworkHelper.ReadString64(br);
                    if (p.ProtocolVersion != 200)
                    {
                        servergameversion = "Minecraft " + p.ProtocolVersion;
                    }
                    if (servergameversion != GameVersion.Version)
                    {
                        throw new Exception(string.Format(invalidversionstr, GameVersion.Version, servergameversion));
                    }
                }
                p.ServerName = NetworkHelper.ReadString64(br);
                p.ServerMotd = NetworkHelper.ReadString64(br);
                p.UserType   = br.ReadByte();
                //connected = true;
                this.serverName = p.ServerName;
                this.ServerMotd = p.ServerMotd;
                ChatLog("---Connected---");
            }
            break;

            case MinecraftServerPacketId.Ping:
            {
            }
            break;

            case MinecraftServerPacketId.LevelInitialize:
            {
                receivedMapStream = new MemoryStream();
                InvokeMapLoadingProgress(0, 0);
            }
            break;

            case MinecraftServerPacketId.LevelDataChunk:
            {
                totalread += 2 + 1024 + 1; if (received.Count < totalread)
                {
                    return(0);
                }
                int          chunkLength             = NetworkHelper.ReadInt16(br);
                byte[]       chunkData               = br.ReadBytes(1024);
                BinaryWriter bw1                     = new BinaryWriter(receivedMapStream);
                byte[]       chunkDataWithoutPadding = new byte[chunkLength];
                for (int i = 0; i < chunkLength; i++)
                {
                    chunkDataWithoutPadding[i] = chunkData[i];
                }
                bw1.Write(chunkDataWithoutPadding);
                MapLoadingPercentComplete = br.ReadByte();
                InvokeMapLoadingProgress(MapLoadingPercentComplete, (int)receivedMapStream.Length);
            }
            break;

            case MinecraftServerPacketId.LevelFinalize:
            {
                totalread += 2 + 2 + 2; if (received.Count < totalread)
                {
                    return(0);
                }
                if (ENABLE_FORTRESS)
                {
                    totalread += 4; if (received.Count < totalread)
                    {
                        return(0);
                    }                                                                     //simulationstartframe
                }
                mapreceivedsizex = NetworkHelper.ReadInt16(br);
                mapreceivedsizez = NetworkHelper.ReadInt16(br);
                mapreceivedsizey = NetworkHelper.ReadInt16(br);
                receivedMapStream.Seek(0, SeekOrigin.Begin);
                if (!ENABLE_FORTRESS)
                {
                    MemoryStream decompressed = new MemoryStream(compression.Decompress(receivedMapStream.ToArray()));
                    if (decompressed.Length != mapreceivedsizex * mapreceivedsizey * mapreceivedsizez +
                        (decompressed.Length % 1024))
                    {
                        //throw new Exception();
                        Console.WriteLine("warning: invalid map data size");
                    }
                    byte[, ,] receivedmap = new byte[mapreceivedsizex, mapreceivedsizey, mapreceivedsizez];
                    {
                        BinaryReader br2  = new BinaryReader(decompressed);
                        int          size = NetworkHelper.ReadInt32(br2);
                        for (int z = 0; z < mapreceivedsizez; z++)
                        {
                            for (int y = 0; y < mapreceivedsizey; y++)
                            {
                                for (int x = 0; x < mapreceivedsizex; x++)
                                {
                                    receivedmap[x, y, z] = br2.ReadByte();
                                }
                            }
                        }
                    }
                    MapStoragePortion.UseMap(receivedmap);
                    Map.Map.MapSizeX = receivedmap.GetUpperBound(0) + 1;
                    Map.Map.MapSizeY = receivedmap.GetUpperBound(1) + 1;
                    Map.Map.MapSizeZ = receivedmap.GetUpperBound(2) + 1;
                    Console.WriteLine("Game loaded successfully.");
                }
                else
                {
                    int simulationstartframe = NetworkHelper.ReadInt32(br);
                    gameworld.LoadState(receivedMapStream.ToArray(), simulationstartframe);
                }
                if (MapLoaded != null)
                {
                    MapLoaded.Invoke(this, new MapLoadedEventArgs()
                        {
                        });
                }
                loadedtime = DateTime.Now;
            }
            break;

            case MinecraftServerPacketId.SetBlock:
            {
                int x;
                int y;
                int z;
                if (ENABLE_FORTRESS)
                {
                    throw new Exception("SetBlock packet");        //no such packet.
                }
                else
                {
                    totalread += 2 + 2 + 2 + 1; if (received.Count < totalread)
                    {
                        return(0);
                    }
                    x = NetworkHelper.ReadInt16(br);
                    z = NetworkHelper.ReadInt16(br);
                    y = NetworkHelper.ReadInt16(br);
                }
                byte type = br.ReadByte();
                try { Map.SetTileAndUpdate(new Vector3(x, y, z), type); }
                catch { Console.WriteLine("Cannot update tile!"); }
            }
            break;

            case MinecraftServerPacketId.SpawnPlayer:
            {
                if (ENABLE_FORTRESS)
                {
                    totalread += 1 + NetworkHelper.StringLength + 4 + 4 + 4 + 1 + 1; if (received.Count < totalread)
                    {
                        return(0);
                    }
                }
                else
                {
                    totalread += 1 + NetworkHelper.StringLength + 2 + 2 + 2 + 1 + 1; if (received.Count < totalread)
                    {
                        return(0);
                    }
                }
                byte   playerid   = br.ReadByte();
                string playername = NetworkHelper.ReadString64(br);
                if (ENABLE_FORTRESS && playerid == 255)
                {
                    spawned = true;
                    break;
                }
                connectedplayers.Add(new ConnectedPlayer()
                    {
                        name = playername, id = playerid
                    });
                if (Clients.Players.ContainsKey(playerid))
                {
                    //throw new Exception();
                }
                Clients.Players[playerid]      = new Player();
                Clients.Players[playerid].Name = playername;
                if (ENABLE_FORTRESS && ((DateTime.Now - loadedtime).TotalSeconds > 10))
                {
                    ReadAndUpdatePlayerPosition(br, playerid);
                }
                if (!ENABLE_FORTRESS)
                {
                    ReadAndUpdatePlayerPosition(br, playerid);
                }
                if (playerid == 255)
                {
                    spawned = true;
                }
            }
            break;

            case MinecraftServerPacketId.PlayerTeleport:
            {
                if (ENABLE_FORTRESS)
                {
                    totalread += 1 + (4 + 4 + 4) + 1 + 1; if (received.Count < totalread)
                    {
                        return(0);
                    }
                }
                else
                {
                    totalread += 1 + (2 + 2 + 2) + 1 + 1; if (received.Count < totalread)
                    {
                        return(0);
                    }
                }
                byte playerid = br.ReadByte();
                ReadAndUpdatePlayerPosition(br, playerid);
            }
            break;

            case MinecraftServerPacketId.PositionandOrientationUpdate:
            {
                totalread += 1 + (1 + 1 + 1) + 1 + 1; if (received.Count < totalread)
                {
                    return(0);
                }
                byte    playerid = br.ReadByte();
                float   x        = (float)br.ReadSByte() / 32;
                float   y        = (float)br.ReadSByte() / 32;
                float   z        = (float)br.ReadSByte() / 32;
                byte    heading  = br.ReadByte();
                byte    pitch    = br.ReadByte();
                Vector3 v        = new Vector3(x, y, z);
                UpdatePositionDiff(playerid, v);
            }
            break;

            case MinecraftServerPacketId.PositionUpdate:
            {
                totalread += 1 + 1 + 1 + 1; if (received.Count < totalread)
                {
                    return(0);
                }
                byte    playerid = br.ReadByte();
                float   x        = (float)br.ReadSByte() / 32;
                float   y        = (float)br.ReadSByte() / 32;
                float   z        = (float)br.ReadSByte() / 32;
                Vector3 v        = new Vector3(x, y, z);
                UpdatePositionDiff(playerid, v);
            }
            break;

            case MinecraftServerPacketId.OrientationUpdate:
            {
                totalread += 1 + 1 + 1; if (received.Count < totalread)
                {
                    return(0);
                }
                byte playerid = br.ReadByte();
                byte heading  = br.ReadByte();
                byte pitch    = br.ReadByte();
                Clients.Players[playerid].Heading = heading;
                Clients.Players[playerid].Pitch   = pitch;
            }
            break;

            case MinecraftServerPacketId.DespawnPlayer:
            {
                totalread += 1; if (received.Count < totalread)
                {
                    return(0);
                }
                byte playerid = br.ReadByte();
                for (int i = 0; i < connectedplayers.Count; i++)
                {
                    if (connectedplayers[i].id == playerid)
                    {
                        connectedplayers.RemoveAt(i);
                    }
                }
                Clients.Players.Remove(playerid);
            }
            break;

            case MinecraftServerPacketId.Message:
            {
                totalread += 1 + NetworkHelper.StringLength; if (received.Count < totalread)
                {
                    return(0);
                }
                byte   unused  = br.ReadByte();
                string message = NetworkHelper.ReadString64(br);
                Chatlines.AddChatline(message);
                ChatLog(message);
            }
            break;

            case MinecraftServerPacketId.DisconnectPlayer:
            {
                totalread += NetworkHelper.StringLength; if (received.Count < totalread)
                {
                    return(0);
                }
                string disconnectReason = NetworkHelper.ReadString64(br);
                throw new Exception(disconnectReason);
            }

            case MinecraftServerPacketId.ExtendedPacketCommand:
            {
                totalread += 1 + 4 + 4; if (received.Count < totalread)
                {
                    return(0);
                }
                int playerid = br.ReadByte();
                int cmdframe = NetworkHelper.ReadInt32(br);
                int length   = NetworkHelper.ReadInt32(br);
                totalread += length; if (received.Count < totalread)
                {
                    return(0);
                }
                byte[] cmd = br.ReadBytes(length);
                gameworld.EnqueueCommand(playerid, cmdframe, cmd);
            }
            break;

            case MinecraftServerPacketId.ExtendedPacketTick:
            {
                totalread += 4 + 4; if (received.Count < totalread)
                {
                    return(0);
                }
                int allowedframe = NetworkHelper.ReadInt32(br);
                int hash         = NetworkHelper.ReadInt32(br);

                totalread += 1; if (received.Count < totalread)
                {
                    return(0);
                }
                int clientscount = br.ReadByte();
                totalread += clientscount * (1 + (3 * 4) + 1 + 1); if (received.Count < totalread)
                {
                    return(0);
                }
                Dictionary <int, PlayerPosition> playerpositions = new Dictionary <int, PlayerPosition>();
                for (int i = 0; i < clientscount; i++)
                {
                    byte playerid = br.ReadByte();
                    //copied
                    float x       = (float)((double)NetworkHelper.ReadInt32(br) / 32);
                    float y       = (float)((double)NetworkHelper.ReadInt32(br) / 32);
                    float z       = (float)((double)NetworkHelper.ReadInt32(br) / 32);
                    byte  heading = br.ReadByte();
                    byte  pitch   = br.ReadByte();
                    playerpositions[playerid] = new PlayerPosition()
                    {
                        position = new Vector3(x, y, z), heading = heading, pitch = pitch
                    };
                }
                gameworld.KeyFrame(allowedframe, hash, playerpositions);
            }
            break;

            default:
            {
                throw new Exception("Invalid packet id");
            }
            }
            return(totalread);
        }