Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="client"></param>
        /// <param name="packet"></param>
        /// <param name="messageNumber"></param>
        public void Parse(Client client, ref byte[] packet, uint messageNumber)
        {
            #region Setup...
            MemoryStream  m_stream = new MemoryStream(packet);
            BinaryReader  m_reader = new BinaryReader(m_stream);
            string        encryptedPassword;
            int           encPasswordLength;
            LoginWrong    nb        = new LoginWrong();
            CheckLogin    cbl       = new CheckLogin();
            CharacterName char_name = new CharacterName();
            #endregion

            switch (messageNumber)
            {
            case 0x22:
                SaltAuthentication salt = new SaltAuthentication();

                // Username and version info
                m_stream.Position    = 24;
                client.accountName   = Encoding.ASCII.GetString(m_reader.ReadBytes(40)).TrimEnd(char.MinValue);
                client.clientVersion = Encoding.ASCII.GetString(m_reader.ReadBytes(20)).TrimEnd(char.MinValue);
                m_reader.Close();
                m_stream.Dispose();

                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("Client '" + client.accountName + "' connected using version '" + client.clientVersion + "'");
                Console.ResetColor();

                // Send Authentication Salt to client
                salt.SendPacket(client, out client.serverSalt);

                break;

            case 0x25:
                // Username and encrypted password
                m_stream.Position = 20;
                string loginAccountName = Encoding.ASCII.GetString(m_reader.ReadBytes(40)).TrimEnd(char.MinValue);
                encPasswordLength = IPAddress.NetworkToHostOrder(m_reader.ReadInt32()) - 1;     // Login Key is Null Terminated. We do not need this Null Terminator.
                encryptedPassword = Encoding.ASCII.GetString(m_reader.ReadBytes(encPasswordLength));
                m_reader.Close();
                m_stream.Dispose();

                if (cbl.IsLoginAllowed(client, loginAccountName) == false)
                {
                    /*
                     * Account name not found or client banned/otherwise not permitted on the server
                     * Note, this is done here not in the above packet (0x22), even though we have
                     * the username or the client will complain. Also a security measure as you can
                     * not tell if an account name is correct or not, only if both the username and
                     * password are correct.
                     *
                     * We also double check that the Account Name is the same as origionally sent
                     * or there could be a possibility to log in with someone elses account.
                     *
                     */

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Client '" + client.accountName + "' banned, not a valid username, or sent a malformed Authentication Packet");
                    Console.ResetColor();

                    client.Send(ref nb.wrongbyte);

                    client.Server.DisconnectClient(client);

                    break;
                }

                if (cbl.IsLoginCorrect(client, encryptedPassword) == false)
                {
                    // Username/Password Incorrect

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Client '" + client.accountName + "' failed Authentication.");
                    Console.ResetColor();

                    client.Send(ref nb.wrongbyte);

                    client.Server.DisconnectClient(client);

                    break;
                }
                else
                {
                    // All's well, send CharacterList Packet

                    CharacterListPacket charlist = new CharacterListPacket();

                    charlist.SendPacket(client, client.accountName);
                }

                break;

            case 0x16:
                // Player selected a character and client sends us selected characters ID
                m_stream.Position = 20;
                int selectedCharID = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                m_reader.Close();
                m_stream.Dispose();

                if (cbl.IsCharacterOnAccount(client, selectedCharID) == false)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Client '" + client.accountName + "' tried to log in as CharID " + selectedCharID + " but it is not on their account!");
                    Console.ResetColor();

                    // NV: Is this really what we want to send? Should find out sometime...
                    client.Send(ref nb.wrongbyte);

                    client.Server.DisconnectClient(client);

                    break;
                }
                if (OnlineChars.IsOnline(selectedCharID) == true)
                {
                    Console.WriteLine("Client '" + client.accountName + "' is trying to login, but the requested character is already logged in.");
                    client.Send(ref nb.wrongbyte);
                    client.Server.DisconnectClient(client);
                    break;
                }
                OnlineChars.SetOnline(selectedCharID);

                IPAddress tempIP;
                if (IPAddress.TryParse(ConfigReadWrite.Instance.CurrentConfig.ZoneIP, out tempIP) == false)
                {
                    IPHostEntry zoneHost = Dns.GetHostEntry(ConfigReadWrite.Instance.CurrentConfig.ZoneIP);
                    foreach (IPAddress ip in zoneHost.AddressList)
                    {
                        if (ip.AddressFamily == AddressFamily.InterNetwork)
                        {
                            tempIP = ip;
                            break;
                        }
                    }
                }
                byte[] ZoneIP   = tempIP.GetAddressBytes();
                byte[] ZonePort = BitConverter.GetBytes(Convert.ToInt32(ConfigReadWrite.Instance.CurrentConfig.ZonePort));

                Byte[] pkt = new byte[]
                {
                    0xDF, 0xDF,
                    0x00, 0x01,
                    0x00, 0x01,
                    0x00, 0x26,
                    0x00, 0x00, 0x00, 0x01,
                    0x00, 0x00, 0x61, 0x5B,                         // Server ID
                    0x00, 0x00, 0x00, 0x17,
                    packet[20], packet[21], packet[22], packet[23], // character ID
                    ZoneIP[0], ZoneIP[1], ZoneIP[2], ZoneIP[3],
                    ZonePort[1], ZonePort[0],
                    0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00
                };

                client.Send(ref pkt);
                break;

            case 0x55:
                /* player ask for 'suggest name'; server sends 'random' name. */
                m_stream.Position = 28;
                char_name.GetRandomName(client, IPAddress.NetworkToHostOrder(m_reader.ReadInt32()));
                break;

            case 0xf:
                /* client created new character */
                Int32 character_id;
                bool  start_in_sl = false;
                char_name.m_accountName = client.accountName;

                /* start reading packet */
                m_stream.Position = 65;
                /* name length */
                int m_name_len = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                /* name (as byte array) */
                char_name.m_name = Encoding.ASCII.GetString(m_reader.ReadBytes(m_name_len));
                /* breed */
                char_name.m_breed = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                /* gender */
                char_name.m_gender = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                /* profession */
                char_name.m_profession = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                /* level (should always be 0 )*/
                char_name.m_level = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                /* lets skip some stuff */
                int skip_len = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                m_stream.Position += (skip_len + 8);
                /* head mesh */
                char_name.m_headmesh = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                /* monster scale */
                char_name.m_monsterscale = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                /* fatness */
                char_name.m_fatness = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                /* start in SL? */
                int sl = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                if (sl == 1)
                {
                    start_in_sl = true;
                }
                /* close reader and stream */
                m_reader.Close();
                m_stream.Dispose();

                /* now you got the data..
                 * do whatever you have to do with it
                 * but please.. in some other class :)
                 */

                /* check name against database
                 *
                 * if name exist, return 0.
                 * if name doesnt exist, creates default char setup and returns character_id
                 *
                 */
                character_id = char_name.CheckAgainstDB();
                if (character_id < 1)
                {
                    char_name.SendNameInUse(client);
                }
                else
                {
                    char_name.SendNameToStartPF(client, start_in_sl, character_id);
                }

                /* reply will work only if character creation
                 * works, so its disabled for now and should be
                 * handled in other class in /Packets/<class name>
                 */
                break;

            case 0x14:
                /* client deletes char */
                Int32 uid;
                /* start reading packet */
                m_stream.Position = 20;
                uid = IPAddress.NetworkToHostOrder(m_reader.ReadInt32());
                char_name.DeleteChar(client, uid);
                break;

            default:
                client.Server.Warning(client, "Client sent unknown message {0}", messageNumber.ToString());
                break;
            }
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="client"></param>
        /// <param name="packet"></param>
        /// <param name="messageNumber"></param>
        public void Parse(Client client, byte[] packet, uint messageNumber)
        {
            #region Setup...
            PacketReader packetReader = new PacketReader(packet);

            string        encryptedPassword;
            int           encPasswordLength;
            byte[]        wrongLogin    = LoginWrong.GetPacket();
            CheckLogin    cbl           = new CheckLogin();
            CharacterName characterName = new CharacterName();
            #endregion

            switch (messageNumber)
            {
            case 0x22:
                SaltAuthentication salt = new SaltAuthentication();

                // Username and version info
                packetReader.ReadBytes(24);
                client.AccountName   = Encoding.ASCII.GetString(packetReader.ReadBytes(40)).TrimEnd(char.MinValue);
                client.ClientVersion = Encoding.ASCII.GetString(packetReader.ReadBytes(20)).TrimEnd(char.MinValue);
                packetReader.Finish();

                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(
                    "Client '" + client.AccountName + "' connected using version '" + client.ClientVersion + "'");
                Console.ResetColor();

                // Send Authentication Salt to client
                client.ServerSalt = salt.SendPacket(client);

                break;

            case 0x25:
                // Username and encrypted password
                // m_stream.Position = 20;
                packetReader.ReadBytes(20);
                string loginAccountName = packetReader.PopString(40).TrimEnd(char.MinValue);
                encPasswordLength = packetReader.PopInt();
                encryptedPassword = packetReader.PopString(encPasswordLength).TrimEnd(char.MinValue);
                packetReader.Finish();

                if (cbl.IsLoginAllowed(client, loginAccountName) == false)
                {
                    /*
                     * Account name not found or client banned/otherwise not permitted on the server
                     * Note, this is done here not in the above packet (0x22), even though we have
                     * the username or the client will complain. Also a security measure as you can
                     * not tell if an account name is correct or not, only if both the username and
                     * password are correct.
                     *
                     * We also double check that the Account Name is the same as origionally sent
                     * or there could be a possibility to log in with someone elses account.
                     *
                     */

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine(
                        "Client '" + client.AccountName
                        + "' banned, not a valid username, or sent a malformed Authentication Packet");
                    Console.ResetColor();

                    client.Send(wrongLogin);

                    client.Server.DisconnectClient(client);

                    break;
                }

                if (cbl.IsLoginCorrect(client, encryptedPassword) == false)
                {
                    // Username/Password Incorrect

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Client '" + client.AccountName + "' failed Authentication.");
                    Console.ResetColor();

                    client.Send(wrongLogin);

                    client.Server.DisconnectClient(client);

                    break;
                }
                else
                {
                    // All's well, send CharacterList Packet

                    CharacterListPacket charlist = new CharacterListPacket();

                    charlist.SendPacket(client, client.AccountName);
                }

                break;

            case 0x16:
                // Player selected a character and client sends us selected characters ID
                packetReader.ReadBytes(20);
                int selectedCharID = packetReader.PopInt();
                packetReader.Finish();

                if (cbl.IsCharacterOnAccount(client, selectedCharID) == false)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine(
                        "Client '" + client.AccountName + "' tried to log in as CharID " + selectedCharID
                        + " but it is not on their account!");
                    Console.ResetColor();

                    // NV: Is this really what we want to send? Should find out sometime...
                    client.Send(wrongLogin);

                    client.Server.DisconnectClient(client);

                    break;
                }
                if (OnlineChars.IsOnline(selectedCharID))
                {
                    Console.WriteLine(
                        "Client '" + client.AccountName
                        + "' is trying to login, but the requested character is already logged in.");
                    client.Send(wrongLogin);
                    client.Server.DisconnectClient(client);
                    break;
                }
                OnlineChars.SetOnline(selectedCharID);

                IPAddress tempIP;
                if (IPAddress.TryParse(ConfigReadWrite.Instance.CurrentConfig.ZoneIP, out tempIP) == false)
                {
                    IPHostEntry zoneHost = Dns.GetHostEntry(ConfigReadWrite.Instance.CurrentConfig.ZoneIP);
                    foreach (IPAddress ip in zoneHost.AddressList)
                    {
                        if (ip.AddressFamily == AddressFamily.InterNetwork)
                        {
                            tempIP = ip;
                            break;
                        }
                    }
                }
                byte[] ZoneIP   = tempIP.GetAddressBytes();
                byte[] ZonePort =
                    BitConverter.GetBytes(Convert.ToInt32(ConfigReadWrite.Instance.CurrentConfig.ZonePort));

                PacketWriter writer = new PacketWriter();
                writer.PushByte(0xDF);
                writer.PushByte(0xDF);
                writer.PushShort(1);    // Packet type
                writer.PushShort(1);
                writer.PushShort(0);    // Packet length (will be set in packet writer)
                writer.PushInt(1);
                writer.PushInt(0x615B); // Server ID
                writer.PushInt(23);     // Packet ID
                writer.PushInt(selectedCharID);
                writer.PushBytes(ZoneIP);
                writer.PushByte(ZonePort[1]);
                writer.PushByte(ZonePort[0]);
                writer.PushShort(0);
                writer.PushInt(0);
                writer.PushInt(0);
                Byte[] pkt = writer.Finish();
                client.Send(pkt);
                break;

            case 0x55:
                /* player ask for 'suggest name'; server sends 'random' name. */
                characterName.GetRandomName(client, packetReader.PopInt());
                packetReader.Finish();
                break;

            case 0xf:
                /* client created new character */
                Int32 characterId;
                bool  startInShadowLands = false;
                characterName.AccountName = client.AccountName;

                /* start reading packet */

                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                // As of 18.5.1 heading for this packet is 69 bytes (65 bytes for lower versions)
                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                packetReader.ReadBytes(69);

                /* name length */
                int nameLen = packetReader.PopInt();
                /* name */
                characterName.Name = packetReader.PopString(nameLen);
                /* breed */
                characterName.Breed = packetReader.PopInt();
                /* gender */
                characterName.Gender = packetReader.PopInt();
                /* profession */
                characterName.Profession = packetReader.PopInt();
                /* level (should always be 0 )*/
                characterName.Level = packetReader.PopInt();
                /* lets skip some stuff */
                int skipLen = packetReader.PopInt();
                packetReader.ReadBytes(skipLen + 8);
                /* head mesh */
                characterName.HeadMesh = packetReader.PopInt();
                /* monster scale */
                characterName.MonsterScale = packetReader.PopInt();
                /* fatness */
                characterName.Fatness = packetReader.PopInt();
                /* start in SL? */
                int sl = packetReader.PopInt();
                if (sl == 1)
                {
                    startInShadowLands = true;
                }
                /* close reader and stream */
                packetReader.Finish();

                /* now you got the data..
                 * do whatever you have to do with it
                 * but please.. in some other class :)
                 */

                /* check name against database
                 *
                 * if name exist, return 0.
                 * if name doesnt exist, creates default char setup and returns character_id
                 *
                 */
                characterId = characterName.CheckAgainstDatabase();
                if (characterId < 1)
                {
                    characterName.SendNameInUse(client);
                }
                else
                {
                    characterName.SendNameToStartPlayfield(client, startInShadowLands, characterId);
                }

                /* reply will work only if character creation
                 * works, so its disabled for now and should be
                 * handled in other class in /Packets/<class name>
                 */
                break;

            case 0x14:
                /* client deletes char */
                Int32 uid;
                /* start reading packet */
                packetReader.ReadBytes(20);
                uid = packetReader.PopInt();
                characterName.DeleteChar(client, uid);
                packetReader.Finish();
                break;

            default:
                packetReader.Finish();
                client.Server.Warning(client, "Client sent unknown message {0}", messageNumber.ToString());
                break;
            }
        }