Пример #1
0
		/// <summary>
		/// Send unencrypted packet to server
		/// </summary>
		public bool SendRaw(Packet pkt)
		{
			m_sendLock.WaitOne();

			byte[] toSend;
			OnSendRawData(pkt, out toSend);
			DataChunk wrap = new DataChunk(toSend.Length) {Data = toSend};
			try
			{
				m_sock.BeginSend(wrap.Data, 0, wrap.Data.Length, SocketFlags.None, _sendCB, wrap);
			}
			catch (SocketException)
			{
				return false;
			}
			return true;
		}
Пример #2
0
		/// <summary>
		/// Processes the data chunk that was received from the server - MUST BE OVERRIDDEN WITH PROCESSING LOGIC
		/// </summary>
		protected abstract void OnReceiveData(DataChunk wrappedData);
Пример #3
0
		/// <summary>
		/// Starts an asyncronous receive operation on the underlying socket
		/// </summary>
		protected void StartDataReceive(DataChunk buffer)
		{
			m_sock.BeginReceive(buffer.Data, 0, buffer.Data.Length, SocketFlags.None, _recvCB, buffer);
		}
Пример #4
0
		//---------------------------------------
		// Send a packet to the server
		//---------------------------------------

		public bool SendPacket(Packet pkt)
		{
			if (!m_sendLock.WaitOne(Constants.ResponseTimeout)) //do one send at a time
				return false;

			byte[] toSend;
			OnSendData(pkt, out toSend);
			DataChunk wrap = new DataChunk(toSend.Length) {Data = toSend};
			try
			{
				m_sock.BeginSend(wrap.Data, 0, wrap.Data.Length, SocketFlags.None, _sendCB, wrap);
			}
			catch (SocketException)
			{
				//connection aborted by hardware errors produce a socketexception.
				return false;
			}
			return true;
		}
Пример #5
0
		/// <summary>
		/// Provides for implementation-specific logic to be called on a successful socket connect() operation
		/// </summary>
		protected virtual void OnConnect()
		{
			DataChunk wrap = new DataChunk();
			m_sock.BeginReceive(wrap.Data, 0, wrap.Data.Length, SocketFlags.None, _recvCB, wrap);
		}
Пример #6
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);
            }
        }
Пример #7
0
 /// <summary>
 /// Processes the data chunk that was received from the server - MUST BE OVERRIDDEN WITH PROCESSING LOGIC
 /// </summary>
 protected abstract void OnReceiveData(DataChunk wrappedData);
Пример #8
0
 /// <summary>
 /// Starts an asyncronous receive operation on the underlying socket
 /// </summary>
 protected void StartDataReceive(DataChunk buffer)
 {
     m_sock.BeginReceive(buffer.Data, 0, buffer.Data.Length, SocketFlags.None, _recvCB, buffer);
 }
Пример #9
0
        /// <summary>
        /// Provides for implementation-specific logic to be called on a successful socket connect() operation
        /// </summary>
        protected virtual void OnConnect()
        {
            DataChunk wrap = new DataChunk();

            m_sock.BeginReceive(wrap.Data, 0, wrap.Data.Length, SocketFlags.None, _recvCB, wrap);
        }