Ejemplo n.º 1
0
 // Use this for initialization
 public override void Init()
 {
     inited         = true;
     netChan        = new NetChan();
     serverCommands = new char[CConstVar.MAX_RELIABLE_COMMANDS][];
     for (int i = 0; i < CConstVar.MAX_RELIABLE_COMMANDS; i++)
     {
         serverCommands[i] = new char[CConstVar.MAX_STRING_CHARS];
     }
 }
Ejemplo n.º 2
0
    public void NetChanTransmitNextFrame(ref NetChan netChan)
    {
        MsgPacket send = new MsgPacket();

        send.Oob = true;
        byte[] send_buf         = new byte[CConstVar.PACKET_MAX_LEN];
        int    fragmentLength   = 0;
        int    outgoingSequence = netChan.outgoingSequence | CConstVar.FRAGMENT_BIT;

        send.WriteInt(outgoingSequence);

        //如果是客户端就发送qport
        if (netChan.src == NetSrc.CLIENT)
        {
            send.WriteInt(CConstVar.Qport);
        }

        send.WriteInt(CheckSum(netChan.challenge, netChan.outgoingSequence));

        fragmentLength = CConstVar.FRAGMENT_SIZE;
        if (netChan.unsentFragmentStart + fragmentLength > netChan.unsentLength)
        {
            fragmentLength = netChan.unsentLength - netChan.unsentFragmentStart;
        }

        send.WriteShort((short)netChan.unsentFragmentStart);
        send.WriteShort((short)fragmentLength);
        send.WriteBufferData(netChan.unsentBuffer, -1, fragmentLength, netChan.unsentFragmentStart);

        //发送数据
        SendPacket(netChan.src, send.CurSize, send.Data, netChan.remoteAddress);

        //存储发送的时间和大小
        netChan.lastSentTime = CDataModel.InputEvent.Milliseconds();
        netChan.lastSentSize = send.CurSize;

        if (CConstVar.ShowPacket > 0)
        {
            CLog.Info("%s send %d : s=%d fragment=%d,%d", netChan.src, send.CurSize, netChan.outgoingSequence, netChan.unsentFragmentStart, fragmentLength);
        }

        netChan.unsentFragmentStart += fragmentLength;

        //现在的情况有点戏剧,因为一个packet如果刚好是fragment的长度
        //那还需要发送第二个packet(长度为0),这样另外一端就知道是否有更多的packet。
        if (netChan.unsentFragmentStart == netChan.unsentLength && CConstVar.FRAGMENT_SIZE != fragmentLength)
        {
            netChan.outgoingSequence++;
            netChan.unsentFragments = false;
        }
    }
Ejemplo n.º 3
0
    //发送的data数据是压缩过的,所以这里oob是true,不进行压缩
    public void NetChanTransmit(ref NetChan netChan, int length, byte[] data)
    {
        MsgPacket send = new MsgPacket();

        byte[] sendBuf = new byte[CConstVar.PACKET_MAX_LEN];
        if (length > CConstVar.PACKET_MAX_LEN)
        {
            CLog.Info("Netchan transmit overflow, length = {0}", length);
        }
        netChan.unsentFragmentStart = 0;

        //fragment large reliable messages
        if (length >= CConstVar.FRAGMENT_SIZE)
        {
            netChan.unsentFragments = true;
            netChan.unsentLength    = length;
            Array.Copy(data, 0, netChan.unsentBuffer, 0, length);

            //只发送第一帧的数据
            NetChanTransmitNextFrame(ref netChan);
        }

        send.Oob = true;
        //写入packet header
        send.WriteInt(netChan.outgoingSequence);

        //发送qport
        if (netChan.src == NetSrc.CLIENT)            //客户端发送到服务器需要qport
        {
            send.WriteShort((short)CConstVar.Qport); //这里qport跟本地监听端口一致
        }

        send.WriteInt(CheckSum(netChan.challenge, netChan.outgoingSequence));         //checksum
        netChan.outgoingSequence++;

        send.WriteData(data, length);         //data的数据写入到packet中

        //发送数据
        SendPacket(netChan.src, send.CurSize, send.Data, netChan.remoteAddress);

        //存储这个包发送的时间和大小。
        netChan.lastSentTime = CDataModel.InputEvent.Milliseconds();
        netChan.lastSentSize = send.CurSize;

        if (CConstVar.ShowPacket > 0)
        {
            CLog.Info("{0} send {1} : outgoSeq = {2} incomSeq = {3}", netChan.src, send.CurSize, netChan.outgoingSequence - 1, netChan.incomingSequence);
        }
    }
Ejemplo n.º 4
0
	// public PlayerState playerState;

	public ClientNode(){
		state = ClientState.FREE;
		netChan = new NetChan();
		netChanQueue = new CircularBuffer<NetChanBuffer>(10); 
		frames = new SvClientSnapshot[CConstVar.PACKET_BACKUP];
		for(int i = 0; i < CConstVar.PACKET_BACKUP; i++){
			frames[i] = new SvClientSnapshot();
		}
		// gEntity = new SharedEntity();
		// gEntity.r = new EntityShared();
		// gEntity.s = new EntityState();
		reliableCommands = new char[CConstVar.MAX_RELIABLE_COMMANDS][];
		for(int i = 0; i < CConstVar.MAX_RELIABLE_COMMANDS; i++){
			reliableCommands[i] = new char[CConstVar.MAX_STRING_CHARS];
		}
		lastUserCmd = new UserCmd();

		messageAcknowledge = -1;
		gamestateMessageNum = -1;

		// playerState = new PlayerState();
	}
Ejemplo n.º 5
0
    public static bool NetChanProcess(ref NetChan netChan, MsgPacket packet)
    {
        bool fragmented     = false;
        int  fragmentStart  = 0;
        int  fragmentLength = 0;

        packet.BeginReadOOB();
        int sequence = packet.ReadInt();

        //检查fragment信息
        if ((sequence & CConstVar.FRAGMENT_BIT) != 0)
        {
            sequence  &= ~CConstVar.FRAGMENT_BIT;
            fragmented = true;
        }
        else
        {
            fragmented = false;
        }

        //如果是服务器,那就读取qport
        if (netChan.src == NetSrc.SERVER)
        {
            packet.ReadShort();             //
        }

        int checkSum = packet.ReadInt();

        //UDP欺骗保护
        if (CheckSum(netChan.challenge, sequence) != checkSum)
        {
            return(false);
        }

        //读取fragment信息
        if (fragmented)
        {
            fragmentStart  = packet.ReadShort();
            fragmentLength = packet.ReadShort();
        }
        else
        {
            fragmentStart  = 0;
            fragmentLength = 0;
        }

        if (CConstVar.ShowPacket > 0)
        {
            if (fragmented)
            {
                CLog.Info("{0} recv {1} bytes : s={2} fragment={3},{4}", netChan.src, packet.CurSize, sequence, fragmentStart, fragmentLength);
            }
            else
            {
                CLog.Info("{0} recv {1} bytes : s={2}", netChan.remoteAddress, packet.CurSize, sequence);
            }
        }

        //丢掉乱序或者重复的packets
        if (sequence <= netChan.incomingSequence)
        {
            if (CConstVar.ShowPacket > 0)
            {
                CLog.Error("%s:Out of order packet %d at %d", netChan.remoteAddress, netChan.dropped, sequence);
            }
            return(false);
        }

        //丢包使得当前的消息不可用
        netChan.dropped = sequence - (netChan.incomingSequence + 1);
        if (netChan.dropped > 0)
        {
            if (CConstVar.ShowNet > 0 || CConstVar.ShowPacket > 0)
            {
                CLog.Info("{0}: Dropped {1} packets at {2}", netChan.remoteAddress, netChan.dropped, sequence);
            }
        }

        //如果当前是可靠消息的最后一个fragment
        //就取得incomming_reliable_sequence
        if (fragmented)
        {
            //确保以正确的顺序添加fragment,可能有packet被丢弃,或者过早地收到了这个packet
            //不会重新构造这个fragment,会等这个packet再次达到
            if (sequence != netChan.fragementSequence)
            {
                netChan.fragementSequence = sequence;
                netChan.fragmentLength    = 0;
            }

            //如果有fragment丢失,打印出日志
            if (fragmentStart != netChan.fragmentLength)
            {
                if (CConstVar.ShowPacket > 0 || CConstVar.ShowNet > 0)
                {
                    CLog.Info("{0}:Dropped a message fragment", netChan.remoteAddress);
                }
                return(false);
            }

            //复制fragment到fragment buffer
            if (fragmentLength < 0 || packet.CurPos + fragmentLength > packet.CurSize || netChan.fragmentLength + fragmentLength > netChan.fragmentBuffer.Length)
            {
                if (CConstVar.ShowPacket > 0 || CConstVar.ShowNet > 0)
                {
                    CLog.Info("{0}:illegal fragment length", netChan.remoteAddress);
                }
                return(false);
            }
            netChan.WriteFragment(packet.Data, packet.CurPos, fragmentLength);

            //如果这不是最后一个fragment,就不处理任何事情(处于中间的fragment的长度是FRAGMENT_SIZE)
            if (fragmentLength == CConstVar.FRAGMENT_SIZE)
            {
                return(false);
            }

            //
            if (netChan.fragmentLength > packet.Data.Length)
            {
                if (CConstVar.ShowPacket > 0 || CConstVar.ShowNet > 0)
                {
                    CLog.Info("{0}:fragmentLength {1} > packet.Data Length", netChan.remoteAddress, netChan.fragmentLength);
                }
                return(false);
            }

            //保证前面的还是sequence
            packet.WriteFirstInt(CNetwork.LittleInt(sequence));
            packet.WriteBufferData(netChan.fragmentBuffer, 4, netChan.fragmentLength);
            // packet.CurSize = netChan.fragmentLength + 4;
            netChan.fragmentLength = 0;
            packet.CurPos          = 4;         //粘贴sequence
            packet.Bit             = 32;        //粘贴sequence

            //客户端没有应答fragment信息
            netChan.incomingSequence = sequence;

            return(true);
        }

        //信息现在可以从当前的信息指针中读取
        netChan.incomingSequence = sequence;

        return(true);
    }
Ejemplo n.º 6
0
	private bool SV_NetChanProcess(ref NetChan netChan, MsgPacket msg)
	{
		return CNetwork.NetChanProcess(ref netChan, msg);
	}