Exemplo n.º 1
0
            private void DoPlay(QueuedAccount q)
            {
                #region Find client area

                if (coordPlay == 0)
                {
                    var v = Settings.LauncherAutologinPoints.Value;

                    if (v != null && !v.PlayButton.IsEmpty)
                    {
                        coordPlay = (uint)v.PlayButton.Y << 16 | v.PlayButton.X;
                    }
                    else
                    {
                        RECT r;
                        if (NativeMethods.GetWindowRect(q.Handle, out r))
                        {
                            var h = r.bottom - r.top;
                            var w = r.right - r.left;

                            coordPlay = (uint)(((uint)(h * 0.725f) << 16) | (uint)(w * 0.738f));
                        }
                    }
                }

                #endregion

                NativeMethods.PostMessage(q.Handle, 0x201, 1, coordPlay);
                NativeMethods.PostMessage(q.Handle, 0x202, 0, coordPlay);
            }
Exemplo n.º 2
0
        private void Schedule(QueuedAccount q, bool nodelay)
        {
            queue.Add(q.ticks, q);

            if (task != null && !task.IsCompleted)
            {
                return;
            }

            if (nodelay)
            {
                if (first != 0)
                {
                    Util.ScheduledEvents.Unregister(OnScheduledCallback);
                }
                first = q.ticks;

                DoQueue();
            }
            else if (first == 0 || q.ticks < first)
            {
                first = q.ticks;
                Util.ScheduledEvents.Register(OnScheduledCallback, q.ticks);
            }
        }
Exemplo n.º 3
0
            private bool IsHandleOkay(QueuedAccount q)
            {
                var p = q.Process;

                p.Refresh();

                return(q.Handle == p.MainWindowHandle);
            }
Exemplo n.º 4
0
            private bool IsHandleOkay(QueuedAccount q)
            {
                var p = q.Process;

                p.Refresh();

                return(q.Handle == Windows.FindWindow.FindMainWindow(p));
            }
Exemplo n.º 5
0
        /// <summary>
        /// The account will be queued to use the API after the specified amount of time.
        /// Adding an account that is already queued will overwrite it, unless it has a unique data object attached.
        /// </summary>
        /// <param name="data">Optional data that will be returned with the response</param>
        public void Schedule(Settings.IAccount account, object data, int millisDelay)
        {
            var now = DateTime.UtcNow;
            var q   = new QueuedAccount(account)
            {
                ticks = now.Ticks / 10000 + millisDelay,
                date  = now,
                data  = data,
            };

            Schedule(q, millisDelay == 0);
        }
Exemplo n.º 6
0
            public void Reschedule(int millisDelay)
            {
                var q = new QueuedAccount(this.Account)
                {
                    ticks    = DateTime.UtcNow.Ticks / 10000 + millisDelay,
                    attempt  = (byte)(Attempt + 1),
                    response = this.Response,
                    date     = this.DateScheduled,
                    data     = this.Data,
                };

                source.Schedule(q, false);
            }
Exemplo n.º 7
0
            private async Task <bool> DoLogin(QueuedAccount q)
            {
                //note: this makes a lot of assumptions and doesn't check anything. a simple test would
                //to be watch for the login and play buttons to change color, confirming that 1) the credentials were entered
                //and 2) the login was successful

                #region Find client area

                if (coordClient == 0)
                {
                    var v = Settings.LauncherAutologinPoints.Value;

                    if (v != null && !v.EmptyArea.IsEmpty)
                    {
                        coordClient = (uint)v.EmptyArea.Y << 16 | v.EmptyArea.X;
                        if (!v.PlayButton.IsEmpty)
                        {
                            coordPlay = (uint)v.PlayButton.Y << 16 | v.PlayButton.X;
                        }
                    }
                    else
                    {
                        RECT r;
                        if (NativeMethods.GetWindowRect(q.Handle, out r))
                        {
                            var h = r.bottom - r.top;
                            var w = r.right - r.left;
                            var x = w * 4 / 5;
                            var y = h / 2;// -100;

                            if (coordPlay == 0)
                            {
                                if (v != null && !v.PlayButton.IsEmpty)
                                {
                                    coordPlay = (uint)v.EmptyArea.Y << 16 | v.EmptyArea.X;
                                }
                                else
                                {
                                    coordPlay = (uint)(((uint)(h * 0.725f) << 16) | (uint)(w * 0.738f));
                                }
                            }

                            do
                            {
                                uint coord  = (uint)(((y + r.top) << 16) | (x + r.left));
                                var  result = NativeMethods.SendMessage(q.Handle, 0x0084, 0, coord);
                                if (result == (IntPtr)1)
                                {
                                    coordClient = (uint)((y << 16) | x);
                                    break;
                                }
                                else if (x > 50)
                                {
                                    x -= 50;
                                }
                                else
                                {
                                    return(false);
                                }
                            }while (true);
                        }
                    }
                }

                #endregion

                var handle = q.Handle;

                //"click" the background area to remove focus - this wouldn't be needed if the email was blank
                NativeMethods.SendMessage(handle, 0x0201, 1, coordClient); //WM_LBUTTONDOWN
                NativeMethods.SendMessage(handle, 0x0202, 0, coordClient); //WM_LBUTTONUP

                //tab back to the email field, which will highlight any existing text
                NativeMethods.SendMessage(handle, 0x0100, 0x09, 0); //WM_KEYDOWN (VK_TAB)

                //paste
                try
                {
                    NativeMethods.keybd_event(0x11, 0, 0, 0); //VK_CONTROL down

                    if (!await DoClipboard(handle, q.Account.Settings.Email, false))
                    {
                        return(false);
                    }
                }
                finally
                {
                    NativeMethods.keybd_event(0x11, 0, 2, 0); //VK_CONTROL up
                }

                //tab to the password field
                NativeMethods.SendMessage(handle, 0x0100, 0x09, 0); //WM_KEYDOWN (VK_TAB)

                //make sure the window hasn't changed
                if (!IsHandleOkay(q))
                {
                    return(false);
                }

                //paste
                try
                {
                    NativeMethods.keybd_event(0x11, 0, 0, 0); //VK_CONTROL down
                    var c = Security.Credentials.ToCharArray(q.Account.Settings.Password);
                    var p = new string(c);
                    Array.Clear(c, 0, c.Length);
                    if (!await DoClipboard(handle, p, true))
                    {
                        return(false);
                    }
                }
                finally
                {
                    NativeMethods.keybd_event(0x11, 0, 2, 0); //VK_CONTROL up
                }

                if (!Settings.DisableAutomaticLogins)
                {
                    //using the home key to serve as an update
                    NativeMethods.SendMessage(handle, 0x0100, 0x24, 0); //WM_KEYDOWN (VK_HOME)

                    //make sure the window hasn't changed, specifically here as it could auto submit a crash report
                    if (!IsHandleOkay(q))
                    {
                        return(false);
                    }

                    //enter to login
                    NativeMethods.PostMessage(handle, 0x0100, 0x0D, 0); //WM_KEYDOWN (VK_RETURN)
                }

                return(true);
            }
Exemplo n.º 8
0
            public void Queue(Account account, Process p)
            {
                lock (this)
                {
                    try
                    {
                        p = Process.GetProcessById(p.Id);
                    }
                    catch
                    {
                        return;
                    }

                    var queued = false;

                    try
                    {
                        var q = new QueuedAccount(account, p);
                        var s = account.Settings;

                        if (s.AutomaticLogin && s.HasCredentials)
                        {
                            q.State = AccountState.WaitingOnLogin;
                        }
                        else if (s.AutomaticPlay && !Settings.DisableAutomaticLogins)
                        {
                            q.State = AccountState.WaitingOnPlay;
                            q.Time  = DateTime.UtcNow;
                            q.Limit = q.Time.AddSeconds(30);
                        }
                        else
                        {
                            return;
                        }

                        if (p.HasExited)
                        {
                            return;
                        }
                        else
                        {
                            q.Handle = p.MainWindowHandle;
                            if (q.Handle == IntPtr.Zero)
                            {
                                return;
                            }
                        }

                        var buffer = new StringBuilder(10);
                        NativeMethods.GetClassName(q.Handle, buffer, buffer.Capacity + 1);
                        if (!buffer.ToString().Equals(LAUNCHER_WINDOW_CLASSNAME))
                        {
                            return;
                        }

                        queue.Enqueue(q);
                        queued = true;
                    }
                    finally
                    {
                        if (!queued)
                        {
                            p.Dispose();
                        }
                    }

                    if (task == null || task.IsCompleted)
                    {
                        task = Task.Factory.StartNew(DoQueue);
                    }
                }
            }
Exemplo n.º 9
0
            private async Task <bool> DoClipboard(IntPtr handle, string text, bool reset, QueuedAccount q)
            {
                using (var cancel = new CancellationTokenSource())
                {
                    var data = new DataObject();

                    if (text != null)
                    {
                        data.SetText(text);
                    }
                    else
                    {
                        data.SetData(System.Windows.Forms.DataFormats.Text, "");
                    }

                    var ctext = reset ? await GetClipboardText() : null;

                    if (!await SetClipboardData(data))
                    {
                        return(false);
                    }

                    var completed = false;
                    var isWaiting = true;

                    EventHandler onRequested = delegate
                    {
                        if (isWaiting)
                        {
                            cancel.Cancel(); //could fail, but will be caught by the event
                        }
                    };

                    data.DataRequested += onRequested;

                    try
                    {
                        NativeMethods.keybd_event(0x11, 0, 0, 0);                                                //VK_CONTROL down
                        NativeMethods.SendMessage(handle, WindowMessages.WM_KEYDOWN, (IntPtr)0x56, IntPtr.Zero); //V
                    }
                    finally
                    {
                        NativeMethods.keybd_event(0x11, 0, 2, 0); //VK_CONTROL up
                    }

                    try
                    {
                        //gw2 could potentially take more than 5s to use the clipboard
                        await Task.Delay(5000, cancel.Token);
                    }
                    catch
                    {
                        completed = true;
                    }

                    isWaiting           = false;
                    data.DataRequested -= onRequested;

                    if (completed)
                    {
                        await Task.Delay(100);
                    }

                    if (reset)
                    {
                        if (!await SetClipboardText(ctext))
                        {
                            //failed to restore clipboard
                        }
                    }

                    return(completed);
                }
            }
Exemplo n.º 10
0
            private async Task <bool> DoLogin(QueuedAccount q)
            {
                #region Launcher type

                if (launcherType == 0)
                {
                    try
                    {
                        if (Directory.Exists(Path.Combine(Path.GetDirectoryName(Settings.GuildWars2.Path.Value), "Gw2.dat")))
                        {
                            launcherType = 2;
                        }
                        else
                        {
                            launcherType = 1;
                        }
                    }
                    catch { }
                }

                #endregion

                #region Find client area

                if (coordClient == 0)
                {
                    var v = Settings.GuildWars2.LauncherAutologinPoints.Value;

                    if (v != null && !v.EmptyArea.IsEmpty)
                    {
                        coordClient = (uint)v.EmptyArea.Y << 16 | v.EmptyArea.X;
                        if (!v.PlayButton.IsEmpty)
                        {
                            coordPlay = (uint)v.PlayButton.Y << 16 | v.PlayButton.X;
                        }
                    }
                    else
                    {
                        RECT r;
                        if (NativeMethods.GetWindowRect(q.Handle, out r))
                        {
                            var h = r.bottom - r.top;
                            var w = r.right - r.left;
                            var x = w * 4 / 5;
                            var y = h / 2;// -100;

                            if (launcherType == 2)
                            {
                                x = w * 9 / 10;
                                y = h * 5 / 6;
                            }

                            if (coordPlay == 0)
                            {
                                if (v != null && !v.PlayButton.IsEmpty)
                                {
                                    coordPlay = (uint)v.EmptyArea.Y << 16 | v.EmptyArea.X;
                                }
                                else if (launcherType == 2)
                                {
                                    coordPlay = (uint)(((uint)(h * 0.766f) << 16) | (uint)(w * 0.905f));
                                }
                                else
                                {
                                    coordPlay = (uint)(((uint)(h * 0.725f) << 16) | (uint)(w * 0.738f));
                                }
                            }

                            do
                            {
                                uint coord  = (uint)(((y + r.top) << 16) | (x + r.left));
                                var  result = NativeMethods.SendMessage(q.Handle, 0x0084, 0, coord);
                                if (result == (IntPtr)1)
                                {
                                    coordClient = (uint)((y << 16) | x);
                                    break;
                                }
                                else if (x > 50)
                                {
                                    x -= 50;
                                }
                                else
                                {
                                    return(false);
                                }
                            }while (true);
                        }
                    }
                }

                #endregion

                var handle = q.Handle;

                //disabling to prevent interference from clicking (changes focus) - it'll still process keyboard input
                Windows.WindowLong.Add(handle, GWL.GWL_STYLE, WindowStyle.WS_DISABLED);

                if (launcherType == 2)
                {
                    //"click" to show the login box
                    NativeMethods.SendMessage(handle, 0x0201, 1, coordPlay); //WM_LBUTTONDOWN
                    NativeMethods.SendMessage(handle, 0x0202, 0, coordPlay); //WM_LBUTTONUP

                    await Task.Delay(100);
                }

                try
                {
                    Action wait = delegate
                    {
                        NativeMethods.SendMessage(handle, 0, 0, 0);
                    };

                    //"click" the background area to remove focus - this wouldn't be needed if the email was blank
                    NativeMethods.SendMessage(handle, 0x0201, 1, coordClient); //WM_LBUTTONDOWN
                    NativeMethods.SendMessage(handle, 0x0202, 0, coordClient); //WM_LBUTTONUP

                    wait();

                    if (!await WaitForKeys(System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.Control, 5000))
                    {
                        return(false);
                    }

                    //tab back to the email field, which will highlight any existing text
                    for (var i = (launcherType == 2 ? 6 : 1); i > 0; --i)
                    {
                        NativeMethods.SendMessage(handle, WindowMessages.WM_KEYDOWN, (IntPtr)0x09, IntPtr.Zero); //VK_TAB
                    }

                    wait();

                    var clipboard = await GetClipboardText();

                    //paste
                    if (!await DoClipboard(handle, q.Account.Settings.Email, false, q))
                    {
                        await SetClipboardText(clipboard);

                        q.Process.Refresh();

                        return(false);
                    }

                    wait();

                    if (!await WaitForKeys(System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.Control, 5000))
                    {
                        return(false);
                    }

                    //tab to the password field
                    NativeMethods.SendMessage(handle, WindowMessages.WM_KEYDOWN, (IntPtr)0x09, IntPtr.Zero); //VK_TAB

                    //make sure the window hasn't changed
                    if (!IsHandleOkay(q))
                    {
                        await SetClipboardText(clipboard);

                        return(false);
                    }

                    //paste
                    var c = Security.Credentials.ToCharArray(q.Account.Settings.Password.ToSecureString());

                    try
                    {
                        #region Password via posting

                        //pasting an empty character to verying it's processing text input
                        if (!await DoClipboard(handle, null, false, q))
                        {
                            await SetClipboardText(clipboard);

                            return(false);
                        }

                        //first posted character will be ignored due to the prior keydown message without a following keyup
                        NativeMethods.PostMessage(handle, WindowMessages.WM_CHAR, IntPtr.Zero, IntPtr.Zero);

                        foreach (var ch in c)
                        {
                            NativeMethods.PostMessage(handle, WindowMessages.WM_CHAR, (IntPtr)ch, IntPtr.Zero);
                        }

                        await Task.Delay(500);

                        #endregion

                        #region Password via clipboard

                        //using the clipboard is more reliable, but makes the password visible

                        //var p = new string(c);
                        //if (!await DoClipboard(handle, p, true, q))
                        //{
                        //    return false;
                        //}

                        #endregion
                    }
                    finally
                    {
                        Array.Clear(c, 0, c.Length);
                    }

                    await SetClipboardText(clipboard);

                    if (!Settings.DisableAutomaticLogins)
                    {
                        wait();

                        //using the home key to serve as an input update
                        //NativeMethods.SendMessage(handle, WindowMessages.WM_KEYDOWN, (IntPtr)0x24, IntPtr.Zero); //VK_HOME

                        if (!await WaitForKeys(System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.Control, 5000))
                        {
                            return(false);
                        }

                        //make sure the window hasn't changed, specifically here as it could auto submit a crash report
                        if (!IsHandleOkay(q))
                        {
                            return(false);
                        }

                        //enter to login
                        NativeMethods.PostMessage(handle, WindowMessages.WM_KEYDOWN, (IntPtr)0x0D, IntPtr.Zero); //VK_RETURN
                    }

                    return(true);
                }
                finally
                {
                    Windows.WindowLong.Remove(handle, GWL.GWL_STYLE, WindowStyle.WS_DISABLED);
                }
            }