Exemplo n.º 1
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 || reply == (byte)InitReply.INIT_MAP_MUTATION) //handle the map mutation: should work with the byte/char weirdness
                                {
                                    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);
            }
        }
Exemplo n.º 2
0
        protected override void OnConnect()
        {
            EODataChunk wrap = new EODataChunk();
            StartDataReceive(wrap);

            m_packetProcessor = new ClientPacketProcessor(); //reset the packet processor to allow for new multis
        }