예제 #1
0
        private void ProcessCharacterListQueryPacket(SubPacket receivedPacket)
        {
            Database             db = new Database();
            CharacterQueryPacket cq = new CharacterQueryPacket();
            string accountName      = cq.ReadAccountName(receivedPacket);

            Console.WriteLine("account name for CL: " + accountName);
            var accountId = db.GetAccountIdFromAccountName(accountName);

            Console.WriteLine("ID for CL: " + accountId);
            var characterList = db.GetListOfCharacters(accountId);
            var packets       = cq.BuildResponsePacket(characterList);

            Console.WriteLine("Character packeted authenticated = " + client.authenticated);
            BasePacket packetsToSend = BasePacket.CreatePacket(packets, client.authenticated, false);

            Console.WriteLine("---Character Query Packet---");
            for (var i = 0; i < characterList.Count; i++)
            {
                int characterId = int.Parse(characterList[i][0]);
                client.CharacterIds[i] = characterId;
            }
            packetsToSend.debugPrintPacket();
            client.QueuePacket(packetsToSend);
        }
예제 #2
0
        public static BasePacket CreatePacket(SubPacket subpacket, bool isAuthed, bool isEncrypted)
        {
            //Create Header
            BasePacketHeader header = new BasePacketHeader();

            byte[] data = null;

            header.isAuthenticated = isAuthed ? (byte)1 : (byte)0;
            header.isEncrypted     = isEncrypted ? (byte)1 : (byte)0;
            header.numSubpackets   = 1;
            header.packetSize      = BASEPACKET_SIZE;
            header.timestamp       = Utils.MilisUnixTimeStampUTC();

            //Get packet size
            header.packetSize += subpacket.header.subpacketSize;

            data = new byte[header.packetSize - 0x10];

            //Add Subpackets
            byte[] subpacketData = subpacket.getBytes();
            Array.Copy(subpacketData, 0, data, 0, subpacketData.Length);

            Debug.Assert(data != null);

            BasePacket packet = new BasePacket(header, data);

            return(packet);
        }
예제 #3
0
        private void PerformCharacterCreate(SubPacket subPacket)
        {
            LoginDatabase         db = new LoginDatabase();
            CharacterCreatePacket cp = new CharacterCreatePacket(subPacket.data);

            try
            {
                db.AddCharacterToDb(ap.userName, cp);
                SubPacket  success    = new SubPacket(GamePacketOpCode.CreateCharacterSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Character created successfully"), SubPacketTypes.GamePacket);
                BasePacket basePacket = BasePacket.CreatePacket(success, client.authenticated, false);
                client.QueuePacket(basePacket);
            }
            catch (MySqlException e)
            {
                ErrorPacket ep = new ErrorPacket();
                SubPacket   packetToSend;
                if (e.Number == (int)ErrorCodes.DuplicateCharacter)
                {
                    packetToSend = ep.buildPacket(GamePacketOpCode.CreateCharacterError, ErrorCodes.DuplicateCharacter, "Character with that name already exists");
                }
                else
                {
                    packetToSend = ep.buildPacket(GamePacketOpCode.CreateCharacterError, ErrorCodes.UnknownDatabaseError, "Unknown database error occurred");
                }

                QueueErrorPacket(packetToSend);
            }
        }
예제 #4
0
        //client in this case will be WorldServer
        private void ProcessHandshake(SubPacket receivedPacket)
        {
            //search connected clients for address
            //send characterid and address from receivedPacket back to worldserver
            HandshakePacket received = new HandshakePacket(receivedPacket.data);

            foreach (var connection in LoginServer.mConnectionList)
            {
                //Console.WriteLine("id present: "+characterIdPresentInClient(received.CharacterId, connection));
                //Console.WriteLine("client id: " + received.CharacterId);
                //Console.WriteLine("connection id: " + connection.CharacterId[0]);

                if (connection.GetIp() == received.ClientAddress && characterIdPresentInClient(received.CharacterId, connection))
                {
                    //TODO: Separate this into a method
                    AcknowledgePacket ack = new AcknowledgePacket(true, received.ClientAddress, received.CharacterId);
                    SubPacket         sp  = new SubPacket(GamePacketOpCode.Acknowledgement, 0, 0, ack.GetBytes(), SubPacketTypes.GamePacket);
                    BasePacket        successPacketToSend = BasePacket.CreatePacket(sp, true, false);
                    AckResponseToWorldServer(successPacketToSend);
                    return;
                }
            }
            AcknowledgePacket ackFailure       = new AcknowledgePacket(true, received.ClientAddress, received.CharacterId);
            SubPacket         fail             = new SubPacket(GamePacketOpCode.Acknowledgement, 0, 0, ackFailure.GetBytes(), SubPacketTypes.GamePacket);
            BasePacket        failPacketToSend = BasePacket.CreatePacket(fail, true, false);

            AckResponseToWorldServer(failPacketToSend);
        }
예제 #5
0
        /// <summary>
        /// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
        /// </summary>
        /// <param name="offset">Current offset in buffer.</param>
        /// <param name="buffer">Incoming buffer.</param>
        /// <returns>Returns either a BasePacket or null if not enough data.</returns>
        public BasePacket BuildPacket(ref int offset, byte[] buffer, int bytesRead)
        {
            BasePacket newPacket = null;

            //Too small to even get length
            if (bytesRead <= offset)
            {
                return(null);
            }

            ushort packetSize = BitConverter.ToUInt16(buffer, offset);

            //Too small to whole packet
            if (bytesRead < offset + packetSize)
            {
                return(null);
            }

            if (buffer.Length < offset + packetSize)
            {
                return(null);
            }

            try
            {
                newPacket = new BasePacket(buffer, ref offset);
            }
            catch (OverflowException e)
            {
                Console.WriteLine(e.ToString());
                return(null);
            }

            return(newPacket);
        }
예제 #6
0
        public static unsafe void DecryptPacket(Blowfish blowfish, ref BasePacket packet)
        {
            byte[] data = packet.data;
            int    size = packet.header.packetSize;

            int offset = 0;

            while (offset < data.Length)
            {
                if (data.Length < offset + SubPacket.SUBPACKET_SIZE)
                {
                    throw new OverflowException("Packet Error: Subpacket was too small");
                }

                SubPacketHeader header;
                fixed(byte *pdata = &data[offset])
                {
                    header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
                }

                if (data.Length < offset + header.subpacketSize)
                {
                    throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
                }

                blowfish.Decipher(data, offset + 0x10, header.subpacketSize - 0x10);

                offset += header.subpacketSize;
            }
        }
예제 #7
0
        private void PerformCharacterCreate(SubPacket subPacket)
        {
            Database db = new Database();
            CharacterCreatePacket cp = new CharacterCreatePacket(subPacket.data);
            int error = db.AddCharacterToDb(ap.userName, cp);

            if (error == -1)
            {
                SubPacket  success    = new SubPacket(GamePacketOpCode.CreateCharacterSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Character created successfully"), SubPacketTypes.GamePacket);
                BasePacket basePacket = BasePacket.CreatePacket(success, client.authenticated, false);
                client.QueuePacket(basePacket);
                //created successfully
            }
            else
            {
                ErrorPacket ep = new ErrorPacket();
                if (error == (int)ErrorCodes.DuplicateCharacter)
                {
                    var packetToSend = ep.buildPacket(GamePacketOpCode.CreateCharacterError, ErrorCodes.DuplicateCharacter, "Character with that name already exists");
                }
                if (error == (int)ErrorCodes.UnknownDatabaseError)
                {
                    var packetToSend = ep.buildPacket(GamePacketOpCode.CreateCharacterError, ErrorCodes.UnknownDatabaseError, "Unknown database error occurred");
                    QueueErrorPacket(packetToSend);
                }
            }
        }
예제 #8
0
        private void ProcessAccountPacket(ClientConnection client, SubPacket packet)
        {
            ap = new AccountPacket();
            ErrorPacket ep = new ErrorPacket();

            ap.Read(packet.GetAccountHeaderBytes(), packet.data);
            if (!ap.register)//if account is logging in
            {
                Database      db      = new Database();
                List <string> account = db.CheckUserInDb(ap.userName, ap.password);
                switch (account.Count)
                {
                case 0:
                    var packetToSend = ep.buildPacket(GamePacketOpCode.AccountError, ErrorCodes.NoAccount, "Account does not exist");
                    Console.WriteLine("Attempted log in for username: {0} pw: {1}, account does not exist", ap.userName, ap.password);
                    QueueErrorPacket(packetToSend);
                    break;

                case 1:
                    //password incorrect
                    packetToSend = ep.buildPacket(GamePacketOpCode.AccountError, ErrorCodes.WrongPassword, "Wrong username or password");
                    Console.WriteLine("Attempted log in for username: {0} pw: {1}, password incorrect", ap.userName, ap.password);
                    QueueErrorPacket(packetToSend);
                    break;

                case 2:
                    //user and password found
                    Console.WriteLine("Username: {0} Password: {1} has logged in successfully", account[0], account[1]);
                    SubPacket success = new SubPacket(GamePacketOpCode.AccountSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Login Successful"), SubPacketTypes.GamePacket);
                    client.authenticated = true;
                    BasePacket basePacket = BasePacket.CreatePacket(success, client.authenticated, false);
                    client.QueuePacket(basePacket);
                    break;

                default:
                    throw new Exception("somehow found more than 2 colums in DB");
                }
            }
            else //account is registering
            {
                Database db        = new Database();
                var      succeeded = db.AddUserToDb(ap.userName, ap.password);
                if (succeeded)
                {
                    Console.WriteLine("Username: {0} Password: {1} has been registered successfully", ap.userName, ap.password);
                    SubPacket  success    = new SubPacket(GamePacketOpCode.RegisterSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Registration Successful"), SubPacketTypes.GamePacket);
                    BasePacket basePacket = BasePacket.CreatePacket(success, false, false);
                    client.QueuePacket(basePacket);
                }
                else
                {
                    var packetToSend = ep.buildPacket(GamePacketOpCode.AccountError, ErrorCodes.DuplicateAccount, "Account already registered");
                    QueueErrorPacket(packetToSend);
                }
            }
        }
예제 #9
0
        private void AckResponseToWorldServer(BasePacket packetToSend)
        {
            packetToSend.header.connectionType = (ushort)BasePacketConnectionTypes.Generic;
            IPAddress[] ip       = Dns.GetHostAddresses("127.0.0.1");
            IPEndPoint  remoteEP = new IPEndPoint(ip[0], 3435);
            Socket      socket   = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            socket.Connect(remoteEP);
            ClientConnection temp = new ClientConnection();

            temp.socket = socket;
            temp.QueuePacket(packetToSend);
            temp.FlushQueuedSendPackets();
        }
예제 #10
0
        /// <summary>
        /// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
        /// </summary>
        /// <param name="offset">Current offset in buffer.</param>
        /// <param name="buffer">Incoming buffer.</param>
        /// <returns>Returns either a BasePacket or null if not enough data.</returns>
        public static BasePacket CreatePacket(ref int offset, byte[] buffer, int bytesRead)
        {
            BasePacket newPacket = null;

            //Too small to even get length
            if (bytesRead <= offset)
            {
                return(null);
            }

            ushort packetSize = BitConverter.ToUInt16(buffer, offset);

            //Too small to whole packet
            if (bytesRead < offset + packetSize)
                return(null); }
예제 #11
0
        private void ProcessCharacterDeleteRequest(SubPacket receivedPacket)
        {
            Database db = new Database();
            CharacterDeletePacket deletePacket = new CharacterDeletePacket(receivedPacket);
            int error = db.DeleteCharacterFromDb(deletePacket.CharId);

            if (error == -1)
            {
                SubPacket  success    = new SubPacket(GamePacketOpCode.CharacterDeleteSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Character deleted successfully"), SubPacketTypes.GamePacket);
                BasePacket basePacket = BasePacket.CreatePacket(success, client.authenticated, false);
                client.QueuePacket(basePacket);
            }
            else
            {
                //send error packet here
            }
        }
예제 #12
0
        public void ProcessPacket(ClientConnection client, BasePacket packet)
        {
            this.client = client;

            //        BasePacket.DecryptPacket(client.blowfish, ref packet);

            //else
            packet.debugPrintPacket();
            List <SubPacket> subPackets = packet.GetSubpackets();

            foreach (SubPacket subPacket in subPackets)
            {
                subPacket.debugPrintSubPacket();

                if (subPacket.header.type == (ushort)SubPacketTypes.Account)
                {
                    ProcessAccountPacket(client, subPacket);
                }

                if (subPacket.header.type == (ushort)SubPacketTypes.GamePacket)
                {
                    switch (subPacket.gameMessage.opcode)
                    {
                    case (ushort)GamePacketOpCode.CreateCharacter:
                        if (CheckCharacterCreatePacket(subPacket))
                        {
                            PerformCharacterCreate(subPacket);
                        }
                        break;

                    case (ushort)GamePacketOpCode.CharacterListQuery:
                        ProcessCharacterListQueryPacket(subPacket);
                        break;

                    case (ushort)GamePacketOpCode.CharacterDeleteQuery:
                        ProcessCharacterDeleteRequest(subPacket);
                        break;

                    case (ushort)GamePacketOpCode.Handshake:
                        ProcessHandshake(subPacket);
                        break;
                    }
                }
            }
        }
예제 #13
0
        public static BasePacket CreatePacket(byte[] data, bool isAuthed, bool isEncrypted)
        {
            Debug.Assert(data != null);

            //Create Header
            BasePacketHeader header = new BasePacketHeader();

            header.isAuthenticated = isAuthed ? (byte)1 : (byte)0;
            header.isEncrypted     = isEncrypted ? (byte)1 : (byte)0;
            header.numSubpackets   = 1;
            header.packetSize      = BASEPACKET_SIZE;
            header.timestamp       = Utils.MilisUnixTimeStampUTC();

            //Get packet size
            header.packetSize += (ushort)data.Length;

            BasePacket packet = new BasePacket(header, data);

            return(packet);
        }
예제 #14
0
        /// <summary>
        /// Default BasePacketConnectionType = zone
        /// </summary>
        /// <param name="subpackets"></param>
        /// <param name="isAuthed"></param>
        /// <param name="isEncrypted"></param>
        /// <returns></returns>
        public static BasePacket CreatePacket(List <SubPacket> subpackets, bool isAuthed, bool isEncrypted, BasePacketConnectionTypes connectionType = BasePacketConnectionTypes.Zone)
        {
            //Create Header
            BasePacketHeader header = new BasePacketHeader();

            byte[] data = null;

            header.isAuthenticated = isAuthed ? (byte)1 : (byte)0;
            header.isEncrypted     = isEncrypted ? (byte)1 : (byte)0;
            header.numSubpackets   = (ushort)subpackets.Count;
            header.packetSize      = BASEPACKET_SIZE;
            header.timestamp       = Utils.MilisUnixTimeStampUTC();
            header.connectionType  = (ushort)connectionType;

            //Get packet size
            foreach (SubPacket subpacket in subpackets)
            {
                header.packetSize += subpacket.header.subpacketSize;
            }

            data = new byte[header.packetSize - 0x10];

            //Add Subpackets
            int offset = 0;

            foreach (SubPacket subpacket in subpackets)
            {
                byte[] subpacketData = subpacket.getBytes();
                Array.Copy(subpacketData, 0, data, offset, subpacketData.Length);
                offset += (ushort)subpacketData.Length;
            }

            Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset);

            BasePacket packet = new BasePacket(header, data);

            return(packet);
        }
예제 #15
0
        public void FlushQueuedSendPackets()
        {
            if (!socket.Connected)
            {
                return;
            }

            while (sendPacketQueue.Count > 0)
            {
                BasePacket packet      = sendPacketQueue.Take();
                byte[]     packetBytes = packet.GetPacketBytes();
                byte[]     buffer      = new byte[0xffff];
                Array.Copy(packetBytes, buffer, packetBytes.Length);
                try
                {
                    socket.Send(packetBytes);
                }
                catch (Exception e)
                {
                    Console.WriteLine(string.Format("Weird case, socket was d/ced: {0}", e));
                }
            }
        }
예제 #16
0
 public void QueuePacket(BasePacket packet)
 {
     sendPacketQueue.Add(packet);
 }
예제 #17
0
        private void ReceiveCallBack(IAsyncResult ar)
        {
            //need to setup buffer of length PacketController
            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            ClientConnection client = (ClientConnection)ar.AsyncState;

            try
            {
                int bytesRead = client.socket.EndReceive(ar);
                Console.WriteLine("bytes read" + bytesRead);
                //allows to pause traffic and restart for debugging purposes.
                bytesRead += client.lastPartialSize;
                if (bytesRead > 0)
                {
                    int offset = 0;

                    //build/compile packets until can no longer or data is finished
                    while (client.socket.Connected)
                    {
                        BasePacket basePacket = BuildPacket(ref offset, client.buffer, bytesRead);
                        if (basePacket == null)
                        {
                            break;
                        }
                        else
                        {
                            client.PacketProcessor.ProcessPacket(client, basePacket);
                        }
                    }
                    //Not all bytes consumed, transfer leftover to beginning
                    if (offset < bytesRead)
                    {
                        Array.Copy(client.buffer, offset, client.buffer, 0, bytesRead - offset);
                    }

                    Array.Clear(client.buffer, bytesRead - offset, client.buffer.Length - (bytesRead - offset));

                    //allows to pause traffic and restart for debugging purposes.
                    client.lastPartialSize = bytesRead - offset;

                    //Build any queued subpackets into basepackets and send
                    client.FlushQueuedSendPackets();

                    if (offset < bytesRead)
                    //need offset since not all bytes consumed
                    {
                        client.socket.BeginReceive(client.buffer, bytesRead - offset, client.buffer.Length - (bytesRead - offset), SocketFlags.None, new AsyncCallback(ReceiveCallBack), client);
                    }
                    else
                    {
                        client.socket.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), client);
                    }
                }
                else
                {
                    Console.WriteLine("Client at {0} has disconnected", client.GetFullAddress());

                    lock (mConnectionList)
                    {
                        client.Disconnect();
                        mConnectionList.Remove(client);
                    }
                }
            }
            catch (SocketException)
            {
                if (client.socket != null)
                {
                    client.socket.Disconnect(false);
                    Console.WriteLine("Client at {0} has disconnected", client.GetFullAddress());

                    lock (mConnectionList)
                    {
                        mConnectionList.Remove(client);
                    }
                }
            }
        }
예제 #18
0
        private void QueueErrorPacket(SubPacket subPacket)
        {
            BasePacket errorBasePacket = BasePacket.CreatePacket(subPacket, client.authenticated, false);

            client.QueuePacket(errorBasePacket);
        }