Пример #1
0
        public void On_CMSG_AUTH_SESSION(PacketClass packet, ClientClass client)
        {
            // _WorldCluster.Log.WriteLine(LogType.DEBUG, "[{0}] [{1}:{2}] CMSG_AUTH_SESSION", Format(TimeOfDay, "hh:mm:ss"), client.IP, client.Port)

            packet.GetInt16();
            var clientVersion   = packet.GetInt32();
            var clientSessionId = packet.GetInt32();
            var clientAccount   = packet.GetString();
            var clientSeed      = packet.GetInt32();
            var clientHash      = new byte[20];

            for (var i = 0; i <= 19; i++)
            {
                clientHash[i] = packet.GetInt8();
            }
            var clientAddOnsSize = packet.GetInt32();

            // DONE: Set client.Account
            var tmp = clientAccount;

            // DONE: Kick if existing
            foreach (var tmpClientEntry in _clusterServiceLocator.WorldCluster.ClienTs)
            {
                if (tmpClientEntry.Value is object)
                {
                    if (tmpClientEntry.Value.Account == tmp)
                    {
                        if (tmpClientEntry.Value.Character is object)
                        {
                            tmpClientEntry.Value.Character.Dispose();
                            tmpClientEntry.Value.Character = null;
                        }

                        tmpClientEntry.Value.Dispose();
                    }
                }
            }

            client.Account = tmp;

            // DONE: Set client.SS_Hash
            var    result = new DataTable();
            string query;

            query = "SELECT sessionkey, gmlevel FROM account WHERE username = '******';";
            _clusterServiceLocator.WorldCluster.GetAccountDatabase().Query(query, ref result);
            if (result.Rows.Count > 0)
            {
                tmp           = result.Rows[0].As <string>("sessionkey");
                client.Access = (AccessLevel)result.Rows[0]["gmlevel"];
            }
            else
            {
                _clusterServiceLocator.WorldCluster.Log.WriteLine(LogType.USER, "[{0}:{1}] AUTH_UNKNOWN_ACCOUNT: Account not in DB!", client.IP, client.Port);
                var responseUnkAcc = new PacketClass(Opcodes.SMSG_AUTH_RESPONSE);
                responseUnkAcc.AddInt8((byte)AuthResult.WOW_FAIL_UNKNOWN_ACCOUNT);
                client.Send(responseUnkAcc);
                return;
            }

            client.Client.PacketEncryption.Hash = new byte[40];
            for (int i = 0, loopTo = Strings.Len(tmp) - 1; i <= loopTo; i += 2)
            {
                client.Client.PacketEncryption.Hash[i / 2] = (byte)Conversion.Val("&H" + Strings.Mid(tmp, i + 1, 2));
            }
            client.Client.PacketEncryption.IsEncryptionEnabled = true;

            // DONE: Disconnect clients trying to enter with an invalid build
            if (clientVersion < REQUIRED_BUILD_LOW || clientVersion > REQUIRED_BUILD_HIGH)
            {
                var invalidVersion = new PacketClass(Opcodes.SMSG_AUTH_RESPONSE);
                invalidVersion.AddInt8((byte)AuthResult.WOW_FAIL_VERSION_INVALID);
                client.Send(invalidVersion);
                return;
            }

            // TODO: Make sure the correct client connected
            // Dim temp() As Byte = System.Text.Encoding.ASCII.GetBytes(clientAccount)
            // temp = Concat(temp, BitConverter.GetBytes(0))
            // temp = Concat(temp, BitConverter.GetBytes(clientSeed))
            // temp = Concat(temp, BitConverter.GetBytes(client.Index))
            // temp = Concat(temp, client.SS_Hash)
            // Dim ShaDigest() As Byte = New System.Security.Cryptography.SHA1Managed().ComputeHash(temp)
            // _WorldCluster.Log.WriteLine(LogType.DEBUG, "Client Hash: {0}", BitConverter.ToString(clientHash).Replace("-", ""))
            // _WorldCluster.Log.WriteLine(LogType.DEBUG, "Server Hash: {0}", BitConverter.ToString(ShaDigest).Replace("-", ""))
            // For i As Integer = 0 To 19
            // If clientHash(i) <> ShaDigest(i) Then
            // Dim responseFail As New PacketClass(OPCODES.SMSG_AUTH_RESPONSE)
            // responseFail.AddInt8(AuthResponseCodes.AUTH_FAILED)
            // client.Send(responseFail)
            // Exit Sub
            // End If
            // Next

            // DONE: If server full then queue, If GM/Admin let in
            if (_clusterServiceLocator.WorldCluster.ClienTs.Count > configurationProvider.GetConfiguration().ServerPlayerLimit & client.Access <= AccessLevel.Player)
            {
                ThreadPool.QueueUserWorkItem(client.EnQueue);
            }
            else
            {
                SendLoginOk(client);
            }

            // DONE: Addons info reading
            var decompressBuffer = new byte[packet.Data.Length - packet.Offset + 1];

            Array.Copy(packet.Data, packet.Offset, decompressBuffer, 0, packet.Data.Length - packet.Offset);
            packet.Data   = _clusterServiceLocator.GlobalZip.DeCompress(decompressBuffer);
            packet.Offset = 0;
            // DumpPacket(packet.Data)

            var addOnsNames  = new List <string>();
            var addOnsHashes = new List <uint>();

            // Dim AddOnsConsoleWrite As String = String.Format("[{0}:{1}] Client addons loaded:", client.IP, client.Port)
            while (packet.Offset < clientAddOnsSize)
            {
                addOnsNames.Add(packet.GetString());
                addOnsHashes.Add(packet.GetUInt32());
                packet.GetInt32(); // Unk7
                packet.GetInt8();  // Unk6
                                   // AddOnsConsoleWrite &= String.Format("{0}{1} AddOnName: [{2,-30}], AddOnHash: [{3:X}]", vbCrLf, vbTab, AddOnsNames(AddOnsNames.Count - 1), AddOnsHashes(AddOnsHashes.Count - 1))
            }
            // _WorldCluster.Log.WriteLine(LogType.DEBUG, AddOnsConsoleWrite)

            // DONE: Build mysql addons query
            // Not needed already - in 1.11 addons list is removed.

            // DONE: Send packet
            var addOnsEnable = new PacketClass(Opcodes.SMSG_ADDON_INFO);

            for (int i = 0, loopTo1 = addOnsNames.Count - 1; i <= loopTo1; i++)
            {
                if (File.Exists(string.Format(@"interface\{0}.pub", addOnsNames[i])) && addOnsHashes[i] != 0x1C776D01U)
                {
                    // We have hash data
                    addOnsEnable.AddInt8(2);                    // AddOn Type [1-enabled, 0-banned, 2-blizzard]
                    addOnsEnable.AddInt8(1);                    // Unk
                    var fs = new FileStream(string.Format(@"interface\{0}.pub", addOnsNames[i]), FileMode.Open, FileAccess.Read, FileShare.Read, 258, FileOptions.SequentialScan);
                    var fb = new byte[257];
                    fs.Read(fb, 0, 257);

                    // NOTE: Read from file
                    addOnsEnable.AddByteArray(fb);
                    addOnsEnable.AddInt32(0);
                    addOnsEnable.AddInt8(0);
                }
                else
                {
                    // We don't have hash data or already sent to client
                    addOnsEnable.AddInt8(2);                    // AddOn Type [1-enabled, 0-banned, 2-blizzard]
                    addOnsEnable.AddInt8(1);                    // Unk
                    addOnsEnable.AddInt32(0);
                    addOnsEnable.AddInt16(0);
                }
            }

            client.Send(addOnsEnable);
            addOnsEnable.Dispose();
        }