예제 #1
0
        /// <summary>
        /// Sends packet to the destination.
        /// </summary>
        public void Send(NetworkMessage msg)
        {
            if (OnSend != null)
            {
                OnSend.BeginInvoke(msg, null, null);
            }

            pipe.Write(msg.GetData(), 0, msg.Length);
        }
예제 #2
0
        public void ProcessFromClient(byte[] buffer)
        {
            int length = buffer.Length;

            Array.Copy(buffer, clientRecvMsg.GetBuffer(), length);
            clientRecvMsg.Length = length;

            OnReceivedDataFromClient(clientRecvMsg.GetData());

            switch (protocol)
            {
            case Protocol.None:
            case Protocol.Login:
                ParseFirstClientMsg();
                break;

            case Protocol.World:
                bool decryptOkay = clientRecvMsg.XteaDecrypt(client.IO.XteaKey);
                if (decryptOkay)
                {
                    clientRecvMsg.Position = 6;
                    int msgLength = (int)clientRecvMsg.GetUInt16() + 8;


                    int position = clientRecvMsg.Position;

                    if (!ParsePacketFromClient(client, clientRecvMsg, serverSendMsg))
                    {
                        //unknown packet
                        byte[] unknown = clientRecvMsg.GetBytes(clientRecvMsg.Length - clientRecvMsg.Position);

                        OnSplitPacketFromClient(unknown[0], unknown);
                    }

                    byte[] data = new byte[clientRecvMsg.Position - position];
                    Array.Copy(clientRecvMsg.GetBuffer(), position, data, 0, data.Length);
                    OnSplitPacketFromClient(data[0], data);
                }
                break;
            }
        }
예제 #3
0
        public void ProcessFromServer(byte[] buffer)
        {
            int length = (int)BitConverter.ToUInt16(buffer, 0) + 2;

            if (length > buffer.Length)
            {
                // Packet is split into multiple chunks
                if (partialPacketSize == 0)
                {
                    // This is the first chunk
                    fullPacketSize = length;
                    Array.Copy(buffer, serverRecvMsg.GetBuffer(), buffer.Length);
                    partialPacketSize = buffer.Length;
                    return;
                }
                else
                {
                    // This is a subsequent chunk
                    Array.Copy(buffer, 0, serverRecvMsg.GetBuffer(), partialPacketSize, buffer.Length);
                    partialPacketSize += buffer.Length;

                    if (partialPacketSize < fullPacketSize)
                    {
                        // Packet is still incomplete
                        return;
                    }
                    else
                    {
                        // Packet is complete
                        serverRecvMsg.Length = fullPacketSize;
                    }
                }
            }
            else
            {
                fullPacketSize    = 0;
                partialPacketSize = 0;
                Array.Copy(buffer, serverRecvMsg.GetBuffer(), length);
                serverRecvMsg.Length = length;
            }

            OnReceivedDataFromServer(serverRecvMsg.GetData());

            switch (protocol)
            {
            case Protocol.Login:
                break;

            case Protocol.World:
                bool decryptOkay = serverRecvMsg.XteaDecrypt(client.IO.XteaKey);
                if (decryptOkay)
                {
                    serverRecvMsg.Position = 6;
                    int msgSize = (int)serverRecvMsg.GetUInt16() + 8;
                    clientSendMsg.Reset();

                    while (serverRecvMsg.Position < msgSize)
                    {
                        int  position = serverRecvMsg.Position;
                        bool parsed   = false;

                        try
                        {
                            parsed = ParsePacketFromServer(client, serverRecvMsg, clientSendMsg);
                        }
                        catch (Exception ex)
                        {
                            WriteDebug(ex.Message + "\nStackTrace: " + ex.StackTrace);
                        }

                        if (!parsed)
                        {
                            if (serverRecvMsg.Length - serverRecvMsg.Position > 0 &&
                                serverRecvMsg.Length < serverRecvMsg.GetBuffer().Length)
                            {
                                byte[] unknown = serverRecvMsg.GetBytes(serverRecvMsg.Length - serverRecvMsg.Position);
                                OnSplitPacketFromServer(unknown[0], unknown);
                            }
                            break;
                        }

                        if (serverRecvMsg.Position - position > 0)
                        {
                            byte[] data = new byte[serverRecvMsg.Position - position];
                            Array.Copy(serverRecvMsg.GetBuffer(), position, data, 0, data.Length);

                            OnSplitPacketFromServer(data[0], data);
                        }
                    }
                }
                break;

            case Protocol.None:
                break;
            }
        }
예제 #4
0
 public NetworkMessage(NetworkMessage msg)
     : this(msg.GetData())
 {
     this.position = msg.position;
 }
예제 #5
0
        private void LoginServerReceived(IAsyncResult ar)
        {
            try
            {
                int dataLength = loginSocket.EndReceive(ar);
                if (dataLength > 0)
                {
                    byte[] tmp = new byte[dataLength];
                    Array.Copy(dataLoginServer, tmp, dataLength);
                    NetworkMessage msg = new NetworkMessage(tmp);
                    msg.PrepareToRead(xteaKey.ToUInt32Array());
                    msg.GetUInt16();
                    while (msg.Position < msg.Length)
                    {
                        byte cmd = msg.GetByte();
                        string message;
                        switch (cmd)
                        {
                            case 0x0A: //Error message
                                message = msg.GetString();
                                if (LoginServer_OnError != null)
                                    LoginServer_OnError(message);
                                break;
                            case 0x0B: //For your information
                                message = msg.GetString();
                                if (LoginServer_FYI != null)
                                    LoginServer_FYI(message);
                                break;
                            case 0x14: //MOTD
                                message = msg.GetString();
                                if (LoginServer_MOTD != null)
                                    LoginServer_MOTD(message);
                                break;
                            case 0x1E: //Patching exe/dat/spr messages
                            case 0x1F:
                            case 0x20:
                                if (LoginServer_Patching != null)
                                    LoginServer_Patching("A new client is available.");
                                return;
                            case 0x28: //Select another login server   
                                if (LoginServer_SelectAnother != null)
                                    LoginServer_SelectAnother("Select another login server.");
                                if (retry)
                                {
                                    if (loginServerIndex < maxLoginServers - 1)
                                    {
                                        loginServerIndex++;
                                        TryLoginServer();
                                    }
                                    else
                                    {
                                        if (LoginServer_CouldNotConnect != null)
                                            LoginServer_CouldNotConnect("Select another login server.");

                                        loginSocket.Disconnect(true);
                                        if (Socket_Disconnected != null)
                                            Socket_Disconnected("dataLength<=0");
                                    }
                                }
                                break;
                            case 0x64: //character list
                                int nChars = (int)msg.GetByte();
                                charList = new CharacterLoginInfo[nChars];

                                for (int i = 0; i < nChars; i++)
                                {
                                    charList[i].CharName = msg.GetString();
                                    charList[i].WorldName = msg.GetString();
                                    charList[i].WorldIP = msg.GetUInt32();
                                    charList[i].WorldIPString = IPBytesToString(BitConverter.GetBytes(charList[i].WorldIP), 0);
                                    charList[i].WorldPort = msg.GetUInt16();
                                }

                                if (LoginServer_CharList != null)
                                    LoginServer_CharList("Charlist received.");

                                loginSocket.Disconnect(true);
                                if (Socket_Disconnected != null)
                                    Socket_Disconnected("Charlist received.");
                                return;
                            default:
                                //Notify about an unknown message
                                if (LoginServer_UnknownMsg != null)
                                    LoginServer_UnknownMsg(msg.GetData().ToHexString());

                                loginSocket.Disconnect(true);
                                if (Socket_Disconnected != null)
                                    Socket_Disconnected("Unknown Message.");
                                break;
                        }
                    }
                }
                else //we didn't receive anything
                {
                    if (LoginServer_ReceivedNothing != null)
                        LoginServer_ReceivedNothing("Nothing received on LoginServerIndex=" + loginServerIndex);
                    if (retry)
                    {
                        if (loginServerIndex < maxLoginServers - 1)
                        {
                            loginServerIndex++;
                            TryLoginServer();
                        }
                        else
                        {
                            if (LoginServer_CouldNotConnect != null)
                                LoginServer_CouldNotConnect("dataLength<=0");

                            loginSocket.Disconnect(true);
                            if (Socket_Disconnected != null)
                                Socket_Disconnected("dataLength<=0");
                        }
                    }
                }
            }
            catch (Exception) {}
        }
예제 #6
0
파일: Pipe.cs 프로젝트: FaNtA91/pokemonapi
        /// <summary>
        /// Sends packet to the destination.
        /// </summary>
        public void Send(NetworkMessage msg)
        {
            if (OnSend != null)
                OnSend.BeginInvoke(msg, null, null);

            pipe.Write(msg.GetData(), 0, msg.Length);
        }
예제 #7
0
 public NetworkMessage(NetworkMessage msg)
     : this(msg.GetData())
 {
     this.position = msg.position;
 }
예제 #8
0
        private void ServerReadCallBack(IAsyncResult ar)
        {
            byte[] serverData = null;
            try
            {
                int read = serverStream.EndRead(ar);

                if (read < 2)
                {
                    Restart();
                    return;
                }

                lastInteraction = DateTime.Now;
                int pSize = (int)BitConverter.ToUInt16(serverRecvMsg.GetBuffer(), 0) + 2;

                while (read < pSize)
                {
                    if (serverStream.CanRead)
                    {
                        read += serverStream.Read(serverRecvMsg.GetBuffer(), read, pSize - read);
                    }
                    else
                    {
                        throw new Exception("Connection broken.");
                    }
                }

                serverRecvMsg.Length = pSize;

                switch (protocol)
                {
                case Protocol.Login:
                    ParseCharacterList();
                    break;

                case Protocol.World:
                    OnReceivedDataFromServer(serverRecvMsg.GetData());
                    serverData = serverRecvMsg.GetData();
                    if (serverRecvMsg.XteaDecrypt(xteaKey))
                    {
                        serverRecvMsg.Position = serverRecvMsg.GetPacketHeaderSize();
                        int msgSize = (int)serverRecvMsg.GetUInt16() + serverRecvMsg.GetPacketHeaderSize() + 2;
                        clientSendMsg.Reset();

                        while (serverRecvMsg.Position < msgSize)
                        {
                            int  position = serverRecvMsg.Position;
                            byte type     = serverRecvMsg.PeekByte();
                            lastReceivedPacketTypes.Push(type);
                            if (!ParsePacketFromServer(client, serverRecvMsg, clientSendMsg))
                            {
                                byte[] unknown = serverRecvMsg.GetBytes(serverRecvMsg.Length - serverRecvMsg.Position);

                                OnSplitPacketFromServer(unknown[0], unknown);

                                WriteDebug("Unknown incoming packet, type: " + type.ToString("X") + ", data: " + unknown.ToHexString());
                                clientSendMsg.AddBytes(unknown);
                                break;
                            }

                            byte[] data = new byte[serverRecvMsg.Position - position];
                            Array.Copy(serverRecvMsg.GetBuffer(), position, data, 0, data.Length);

                            OnSplitPacketFromServer(data[0], data);
                        }

                        if (AllowIncomingModification &&
                            clientSendMsg.Length > clientSendMsg.GetPacketHeaderSize() + 2)
                        {
                            clientSendMsg.InsetLogicalPacketHeader();
                            clientSendMsg.PrepareToSend(xteaKey);

                            SendToClient(clientSendMsg.GetData());
                        }
                        else
                        {
                            SendToClient(serverData);
                        }
                    }
                    else
                    {
                        SendToClient(serverData);
                    }

                    serverStream.BeginRead(serverRecvMsg.GetBuffer(), 0, 2, new AsyncCallback(ServerReadCallBack), null);
                    break;

                case Protocol.None:
                    SendToClient(serverRecvMsg.GetData());
                    break;
                }
            }
            catch (System.IO.IOException) { }
            catch (ObjectDisposedException) { }
            catch (Exception ex)
            {
                WriteDebug(ex.ToString());

                if (serverData != null)
                {
                    SendToClient(serverData);
                    serverStream.BeginRead(serverRecvMsg.GetBuffer(), 0, 2, new AsyncCallback(ServerReadCallBack), null);
                }
                //Restart();
            }
        }
예제 #9
0
        private void ClientReadCallBack(IAsyncResult ar)
        {
            byte[] clientData = null;
            try
            {
                int read = clientStream.EndRead(ar);

                if (read < 2)
                {
                    Restart();
                    return;
                }

                int pSize = (int)BitConverter.ToUInt16(clientRecvMsg.GetBuffer(), 0) + 2;

                while (read < pSize)
                {
                    if (clientStream.CanRead)
                    {
                        read += clientStream.Read(clientRecvMsg.GetBuffer(), read, pSize - read);
                    }
                    else
                    {
                        throw new Exception("Connection broken.");
                    }
                }

                clientRecvMsg.Length = pSize;

                switch (protocol)
                {
                case Protocol.None:
                    ParseFirstClientMsg();
                    break;

                case Protocol.World:
                    OnReceivedDataFromClient(clientRecvMsg.GetData());

                    clientData = clientRecvMsg.GetData();

                    if (clientRecvMsg.XteaDecrypt(xteaKey))
                    {
                        clientRecvMsg.Position = clientRecvMsg.GetPacketHeaderSize();
                        int msgLength = (int)clientRecvMsg.GetUInt16() + 8;
                        serverSendMsg.Reset();


                        int position = clientRecvMsg.Position;

                        if (!ParsePacketFromClient(client, clientRecvMsg, serverSendMsg))
                        {
                            //unknown packet
                            byte[] unknown = clientRecvMsg.GetBytes(clientRecvMsg.Length - clientRecvMsg.Position);

                            OnSplitPacketFromClient(unknown[0], unknown);

                            WriteDebug("Unknown outgoing packet: " + unknown.ToHexString());
                            serverSendMsg.AddBytes(unknown);
                        }

                        byte[] data = new byte[clientRecvMsg.Position - position];
                        Array.Copy(clientRecvMsg.GetBuffer(), position, data, 0, data.Length);
                        OnSplitPacketFromClient(data[0], data);

                        if (AllowOutgoingModification &&
                            serverSendMsg.Length > serverSendMsg.GetPacketHeaderSize() + 2)
                        {
                            serverSendMsg.InsetLogicalPacketHeader();
                            serverSendMsg.PrepareToSend(xteaKey);

                            SendToServer(serverSendMsg.GetData());
                        }
                        else
                        {
                            SendToServer(clientData);
                        }
                    }
                    else
                    {
                        SendToServer(clientData);
                    }
                    clientStream.BeginRead(clientRecvMsg.GetBuffer(), 0, 2, new AsyncCallback(ClientReadCallBack), null);
                    break;

                case Protocol.Login:
                    break;
                }
            }
            catch (ObjectDisposedException) { /*We don't have to log this exception. */ }
            catch (System.IO.IOException ex) { WriteDebug(ex.ToString()); }
            catch (Exception ex)
            {
                WriteDebug(ex.ToString());
                if (clientData != null)
                {
                    SendToServer(clientData);
                }
            }
        }
예제 #10
0
        public bool Send(SendMethod method)
        {
            if (msg == null)
            {
                msg = new NetworkMessage(Client, 4048);
            }

            switch (method)
            {
            case SendMethod.Proxy:
                lock (msgLock)
                {
                    msg.Reset();
                    ToNetworkMessage(msg);

                    if (msg.Length > 8)
                    {
                        msg.InsetLogicalPacketHeader();
                        msg.PrepareToSend();

                        if (Destination == PacketDestination.Client)
                        {
                            Client.IO.Proxy.SendToClient(msg.GetData());
                        }
                        else if (Destination == PacketDestination.Server)
                        {
                            Client.IO.Proxy.SendToServer(msg.GetData());
                        }

                        return(true);
                    }
                }
                break;

            case SendMethod.HookProxy:
                lock (msgLock)
                {
                    msg.Reset();
                    ToNetworkMessage(msg);

                    if (msg.Length > 8)
                    {
                        msg.InsetLogicalPacketHeader();
                        msg.PrepareToSend();

                        Pipes.HookSendToServerPacket.Send(Client, msg.GetData());

                        return(true);
                    }
                }
                break;

            case SendMethod.Memory:
                lock (msgLock)
                {
                    msg.Reset();
                    ToNetworkMessage(msg);
                    if (Destination == PacketDestination.Server)
                    {
                        if (msg.Length > 8)
                        {
                            msg.InsetLogicalPacketHeader();
                            msg.PrepareToSend();

                            return(SendPacketToServerByMemory(Client, msg.GetData()));
                        }
                    }
                    else if (Destination == PacketDestination.Client)
                    {
                        byte[] data = new byte[msg.GetData().Length - 8];
                        Array.Copy(msg.GetData(), 8, data, 0, data.Length);
                        SendPacketToClientByMemory(Client, data);
                    }
                }
                break;
            }

            return(false);
        }