Пример #1
0
 public void Init()
 {
     snap = new ClientSnapshot();
     // mouseDx = new int[3];
     // mouseDy = new int[3];
     entityBaselines = new EntityState[CConstVar.MAX_SNAPSHOT_ENTITIES * CConstVar.PACKET_BACKUP];
     // outPackets = new OutPacket[CConstVar.PACKET_BACKUP];
 }
Пример #2
0
 public override void Update(GameTime gameTime)
 {
     if (!world.Player.IsDead)
     {
         ClientSnapshot snapshot = ClientSnapshot.SnapShot(world);
         if (previousSnapshot.playerData != snapshot.playerData)
         {
             SendMessage(MessageContentType.PlayerUpdate, snapshot.playerData.ID, snapshot.playerData);
         }
     }
     // read new data from server
     server.Update();
 }
Пример #3
0
    private void DeltaEntity(MsgPacket msg, ClientSnapshot frame, int newNum, ref EntityState old, bool unchanged)
    {
        EntityState state = clientActive.parseEntities[clientActive.parseEntitiesIndex & (CConstVar.MAX_PARSE_ENTITIES - 1)];

        if (unchanged)
        {
            old.CopyTo(state);
        }
        else
        {
            msg.ReadDeltaEntity(ref old, ref state, newNum);
        }
        if (state.entityIndex == (CConstVar.MAX_GENTITIES - 1))
        {
            return;
        }
        clientActive.parseEntitiesIndex++;
        frame.numEntities++;
    }
Пример #4
0
    //TODO:这里有问题,这个函数做了一个假设,可以新增entity,但是不能删除entity,因为删除了,index就会出现错乱
    //不过其实问题不大,因为是用的index,所以entity变换成为另外一个entity也不是问题(删除的话先不管,如果新增,就补位到那个entity的位置)。
    private void ParseEntities(MsgPacket packet, ClientSnapshot oldframe, ClientSnapshot newframe)
    {
        int         newIndex;
        EntityState oldState = new EntityState();
        int         oldParseIndex, oldEntIndex;

        newframe.parseEntitiesIndex = clientActive.parseEntitiesIndex;
        newframe.numEntities        = 0;

        //
        oldParseIndex = 0;
        // oldState =
        if (oldframe == null)
        {
            oldEntIndex = 99999;
        }
        else
        {
            if (oldParseIndex >= oldframe.numEntities)
            {
                oldEntIndex = 99999;
            }
            else
            {
                oldState    = clientActive.parseEntities[(oldframe.parseEntitiesIndex + oldParseIndex) & (CConstVar.MAX_PARSE_ENTITIES - 1)];
                oldEntIndex = oldState.entityIndex;
            }
        }

        while (true)
        {
            //读取entity的索引值
            //服务器会根据number从小到大排序,保证小的总在前面
            newIndex = packet.ReadBits(CConstVar.GENTITYNUM_BITS);
            if (newIndex == (CConstVar.MAX_GENTITIES - 1))
            {
                break;
            }

            if (packet.CurPos > packet.CurSize)
            {
                CLog.Error("ParseEntities: end of message");
                break;
            }

            while (oldEntIndex < newIndex)
            {
                //来自旧数据包中的一个或者多个entity没有发生变化
                if (CConstVar.ShowNet == 3)
                {
                    CLog.Info("entity unchanged: %d", oldEntIndex);
                }
                DeltaEntity(packet, newframe, oldEntIndex, ref oldState, true);

                oldParseIndex++;

                if (oldParseIndex >= oldframe.numEntities)
                {
                    oldEntIndex = 99999;
                }
                else
                {
                    oldState    = clientActive.parseEntities[(oldframe.parseEntitiesIndex + oldParseIndex) & (CConstVar.MAX_PARSE_ENTITIES - 1)];
                    oldEntIndex = oldState.entityIndex;
                }
            }

            if (oldEntIndex == newIndex)
            {
                //增量来自于前一帧
                if (CConstVar.ShowNet == 3)
                {
                    CLog.Info("delta entity: %d", newIndex);
                }
                DeltaEntity(packet, newframe, newIndex, ref oldState, false);

                oldParseIndex++;

                if (oldParseIndex >= oldframe.numEntities)
                {
                    oldEntIndex = 99999;
                }
                else
                {
                    oldState    = clientActive.parseEntities[(oldframe.parseEntitiesIndex + oldParseIndex) & (CConstVar.MAX_PARSE_ENTITIES - 1)];
                    oldEntIndex = oldState.entityIndex;
                }
                continue;
            }

            //上一帧中没有对应的数据
            if (oldEntIndex > newIndex)
            {
                if (CConstVar.ShowNet == 3)
                {
                    CLog.Info("base line entity: %d", newIndex);
                }
                DeltaEntity(packet, newframe, newIndex, ref clientActive.entityBaselines[newIndex], false);
                continue;
            }
        }

        //oldframe内剩下的entities都直接复制过去
        //被标记为删除的entity,parseEntitiesIndex不会增加,然后被后续的entity覆盖
        while (oldEntIndex != 99999)
        {
            if (CConstVar.ShowNet == 3)
            {
                CLog.Info("unchanged entity: %d", oldEntIndex);
            }
            DeltaEntity(packet, newframe, oldEntIndex, ref oldState, true);

            oldParseIndex++;

            if (oldParseIndex >= oldframe.numEntities)
            {
                oldEntIndex = 99999;
            }
            else
            {
                oldState    = clientActive.parseEntities[(oldframe.parseEntitiesIndex + oldParseIndex) & (CConstVar.MAX_PARSE_ENTITIES - 1)];
                oldEntIndex = oldState.entityIndex;
            }
        }
    }
Пример #5
0
    //如果snapshot解析正确,它会被复制到snap中,并被存储在snapshots[]
    //如果snapshot因为任何原因不合适,不会任何改变任何state
    public void ParseSnapshot(MsgPacket packet)
    {
        int            len;
        ClientSnapshot old     = new ClientSnapshot();
        ClientSnapshot newSnap = new ClientSnapshot();
        int            deltaNum;
        int            oldMessageNum;
        int            i, packetNum;

        var connection = CDataModel.Connection;

        //获取可靠的acknowledge number
        //所有从服务器发送到客户端的消息reliableAcknowledge = ReadLong();
        //将新的snapshot读取到临时缓冲中
        //如果合适就复制到snap中
        newSnap.serverCommandNum = connection.serverCommandSequence;
        newSnap.serverTime       = packet.ReadInt();

        this.paused = 0;

        newSnap.messageNum = connection.serverMessageSequence;

        deltaNum = packet.ReadByte();
        if (deltaNum == 0)
        {
            newSnap.deltaNum = -1;
        }
        else
        {
            newSnap.deltaNum = newSnap.messageNum - deltaNum;
        }
        newSnap.snapFlags = (SnapFlags)packet.ReadByte();

        // var clientActive = CDataModel.GameState.ClientActive;
        if (newSnap.deltaNum <= 0)
        {
            newSnap.valid          = true;
            old                    = null;
            connection.demoWaiting = false;
        }
        else
        {
            old = clientActive.snapshots[newSnap.deltaNum & CConstVar.PACKET_MASK];
            if (!old.valid)
            {
                CLog.Error("old snapshot is invalid");
            }
            else if (old.messageNum != newSnap.deltaNum)
            {
                CLog.Info("Delta frame too old");
            }
            else if (clientActive.parseEntitiesIndex - old.parseEntitiesIndex > CConstVar.MAX_PARSE_ENTITIES - CConstVar.MAX_SNAPSHOT_ENTITIES)
            {
                CLog.Info("Delta parseEntitiesNum too old");
            }
            else
            {
                newSnap.valid = true;
            }
        }

        // CLog.Info("begin playerstate at pos:{0}", packet.CurPos);
        if (old != null)
        {
            packet.ReadDeltaPlayerstate(old.playerState, newSnap.playerState);
        }
        else
        {
            // PlayerState tmpP = default(PlayerState);
            packet.ReadDeltaPlayerstate(null, newSnap.playerState);
        }

        // CLog.Info("begin packet entities at pos:{0}", packet.CurPos);
        ParseEntities(packet, old, newSnap);

        //如果不合适,就弹出所有的内容,因为它已经被读出。
        if (!newSnap.valid)
        {
            return;
        }

        //清除最后接收到的帧和当前帧之间的所有帧的valid标记,所以如果有丢掉的消息
        //它看起来就不会像是从buffer中增量更新而得到的合适的帧。
        oldMessageNum = clientActive.snap.messageNum + 1;

        if (newSnap.messageNum - oldMessageNum >= CConstVar.PACKET_BACKUP)
        {
            oldMessageNum = newSnap.messageNum - (CConstVar.PACKET_BACKUP - 1);
        }
        for (; oldMessageNum < newSnap.messageNum; oldMessageNum++)
        {
            clientActive.snapshots[oldMessageNum & CConstVar.PACKET_MASK].valid = false;
        }

        clientActive.snap      = newSnap;
        clientActive.snap.ping = 999;
        for (i = 0; i < CConstVar.PACKET_BACKUP; i++)
        {
            packetNum = (connection.NetChan.outgoingSequence - 1 - i) & CConstVar.PACKET_MASK;
            if (clientActive.snap.playerState.commandTime >= clientActive.outPackets[packetNum].serverTime)
            {
                clientActive.snap.ping = this.realTime - clientActive.outPackets[packetNum].realTime;
                break;
            }
        }

        //保存当前帧在缓冲中,用来后来做增量比较
        clientActive.snapshots[clientActive.snap.messageNum & CConstVar.PACKET_MASK] = clientActive.snap;

        if (CConstVar.ShowNet == 3)
        {
            CLog.Info("snapshot: {0} delta: {1} ping:{2}", clientActive.snap.messageNum, clientActive.snap.deltaNum, clientActive.snap.ping);
        }

        clientActive.newSnapshots = true;
    }
Пример #6
0
 public override void SnapShot()
 {
     previousSnapshot = ClientSnapshot.SnapShot(world);
 }