示例#1
0
        protected override void OnConnect()
        {
            EODataChunk wrap = new EODataChunk();

            StartDataReceive(wrap);

            m_packetProcessor = new ClientPacketProcessor();             //reset the packet processor to allow for new multis
        }
示例#2
0
        protected override void OnReceiveData(DataChunk state)
        {
            EODataChunk wrap = (EODataChunk)state;

            if (wrap.Data.Length == 0)
            {
                wrap.State = EODataChunk.DataReceiveState.NoData;
            }
            try
            {
                switch (wrap.State)
                {
                case EODataChunk.DataReceiveState.ReadLen1:
                {
                    wrap.RawLength[0] = wrap.Data[0];
                    wrap.State        = EODataChunk.DataReceiveState.ReadLen2;
                    wrap.Data         = new byte[EODataChunk.BUFFER_SIZE];
                    StartDataReceive(wrap);
                    break;
                }

                case EODataChunk.DataReceiveState.ReadLen2:
                {
                    wrap.RawLength[1] = wrap.Data[0];
                    wrap.State        = EODataChunk.DataReceiveState.ReadData;
                    wrap.Data         = new byte[Packet.DecodeNumber(wrap.RawLength)];
                    StartDataReceive(wrap);
                    break;
                }

                case EODataChunk.DataReceiveState.ReadData:
                {
                    byte[] data = new byte[wrap.Data.Length];
                    Array.Copy(wrap.Data, data, data.Length);
                    m_packetProcessor.Decode(ref data);

                    //This block handles receipt of file data that is transferred to the client.
                    //It should make file transfer nuances pretty transparent to the client.
                    //The header for files stored in a Packet type is always as follows: FAMILY_INIT, ACTION_INIT, (InitReply)
                    //A 3-byte offset is found throughout the code that handles creating these files.
                    if (data[0] == 255 && data[1] == 255)                                     //INIT_INIT packet! check to see if expecting a file or player list
                    {
                        Packet pkt   = new Packet(data);
                        byte   reply = pkt.GetChar();
                        if (ExpectingFile)
                        {
                            int dataGrabbed = 0;

                            //find first zero byte
                            int pktOffset = 0;
                            for (; pktOffset < data.Length; ++pktOffset)
                            {
                                if (data[pktOffset] == 0)
                                {
                                    break;
                                }
                            }

                            //continue receiving until we have grabbed enough data to fill the allocated packet buffer
                            do
                            {
                                byte[] fileBuffer  = new byte[pkt.Length - pktOffset];
                                int    nextGrabbed = ReceiveRaw(ref fileBuffer);
                                Array.Copy(fileBuffer, 0, data, dataGrabbed + 3, data.Length - (dataGrabbed + pktOffset));
                                dataGrabbed += nextGrabbed;
                            } while (dataGrabbed < pkt.Length - pktOffset);

                            if (pktOffset > 3)
                            {
                                data = data.SubArray(0, pkt.Length - (pktOffset - 3));
                            }

                            //rewrite the InitReply with the correct value (retrieved with GetChar, server sends with GetByte for other reply types)
                            data[2] = reply;
                        }
                        else if (ExpectingPlayerList)
                        {
                            //online list sends a char... rewrite it with a byte so it is parsed correctly.
                            data[2] = reply;
                        }
                    }

                    ThreadPool.QueueUserWorkItem(_handlePacket, new Packet(data));
                    EODataChunk newWrap = new EODataChunk();
                    StartDataReceive(newWrap);
                    break;
                }

                default:
                {
                    Console.WriteLine("ERROR: Invalid data wrapper state in _recvCB (should be ReadLen1, ReadLen2, or ReadData). Closing connection.");
                    Disconnect();
                    break;
                }
                }
            }
            catch (SocketException se)
            {
                //in the process of disconnecting
                Console.WriteLine("There was a SocketException with SocketErrorCode {0} in _recvCB", se.SocketErrorCode);
            }
        }