Нажатие на движущийся объект в игре - PullRequest
0 голосов
/ 29 мая 2018

Я сделал несколько очень простых ботов для некоторых веб-игр и хотел перейти к другим играм, которые требуют использования более продвинутых функций.

Я использовал pyautogui для работы с ботами в сетиигры, и это было легко, потому что все изображения статичны (не движутся), но когда я хочу щелкнуть что-то в игре, что движется, это может быть Персонаж или Существо, бегущее вокруг pyautogui, не очень эффективно, потому что оно выглядитдля пикселей / цветов, которые абсолютно одинаковы.

Пожалуйста, предложите какие-либо ссылки или любые библиотеки или функции, которые могут обнаружить модель или символ, даже если персонаж движется?

Вот примерчто-то, на что я хотел бы нажать:

Движущееся изображение существа Gif

Спасибо.

Ответы [ 2 ]

0 голосов
/ 21 июня 2018

Если цвета мобов несколько легко отличить от фона, вы можете использовать согласование пикселей pyautogui.

import pyautogui
screen = pyautogui.screenshot()

# Use this to scan the area of the screen where the mob appears.
(R, G, B) = screen.getpixel((x, y))

# Compare to mob color

Если цвета варьируются, вы можете использовать допуск цвета:

pyautogui.pixelMatchesColor(x, y, (R, G, B), tolerance=5)
0 голосов
/ 29 мая 2018

Я заметил, что изображение, на которое вы ссылаетесь, представляет собой гриф моба из world of warcraft.

В качестве хобби я в последние несколько лет создавал и отключал ботов для MMO.

Нет конкретных библиотек python, которые позволили бы вам делать то, о чем вы просите, о чем я знаю;однако, взяв WoW в качестве примера ...

Если вы используете Windows в качестве рассматриваемой ОС, вы будете использовать вызовы Windows API для управления целевым процессом вашей игры (здесь wow.exe).

Существует два основных подхода к этому:

1) Вне процесса - вы все делаете, считывая значения памяти из известных смещений, и отвечаете, используя Windows API для симуляции мыши и/ или ввод с клавиатуры (на ваш выбор).

1a) Я быстро упомяну, что хотя для большинства современных игр это не вариант (из-за встроенного античит-кода), вы также можете манипулировать игройзаписав прямо в память.В WAR (Warhammer Online), когда он еще был жив, я создал робота-гринда, который записывал в память всякий раз, когда это было возможно, так как они не позволяли punkbuster защищать игру от этого.WoW защищен печально известным «Стражем».

2) Инъекция DLL - WoW имеет встроенный API, созданный в LUA.В результате на протяжении многих лет многие программисты и хакеры-любители разбирали двоичный файл, чтобы раскрыть его внутреннюю работу.Вы можете посетить форум по редактированию памяти на OwneCore.com , если хотите работать с WoW.Многие из них поделились известными смещениями в двоичном коде, где можно подключиться к функциям LUA и, в результате, напрямую выполнить внутриигровые действия, а также получить необходимую информацию.Некоторые даже поделились своими собственными DLL

. Вы упомянули, что щелкали внутриигровые 3D-объекты.В заключение я поделюсь с вами фрагментом кода, который выкладывает на OwnerCore и который позволяет сделать именно это.Этот пример охватывает использование как смещений памяти, так и вызовов игровых функций:

using System;
using SlimDX;

namespace VanillaMagic
{
    public static class Camera
    {
        internal static IntPtr BaseAddress
        {
            get
            {
                var ptr = WoW.hook.Memory.Read<IntPtr>(Offsets.Camera.CameraPtr, true);
                return WoW.hook.Memory.Read<IntPtr>(ptr + Offsets.Camera.CameraPtrOffset);
            }
        }

    private static Offsets.CGCamera cam => WoW.hook.Memory.Read<Offsets.CGCamera>(BaseAddress);

    public static float X => cam.Position.X;
    public static float Y => cam.Position.Y;
    public static float Z => cam.Position.Z;
    public static float FOV => cam.FieldOfView;
    public static float NearClip => cam.NearClip;
    public static float FarClip => cam.FarClip;
    public static float Aspect => cam.Aspect;

    private static Matrix Matrix
    {
        get
        {
            var bCamera = WoW.hook.Memory.ReadBytes(BaseAddress + Offsets.Camera.CameraMatrix, 36);
            var m = new Matrix();
            m[0, 0] = BitConverter.ToSingle(bCamera, 0);
            m[0, 1] = BitConverter.ToSingle(bCamera, 4);
            m[0, 2] = BitConverter.ToSingle(bCamera, 8);
            m[1, 0] = BitConverter.ToSingle(bCamera, 12);
            m[1, 1] = BitConverter.ToSingle(bCamera, 16);
            m[1, 2] = BitConverter.ToSingle(bCamera, 20);
            m[2, 0] = BitConverter.ToSingle(bCamera, 24);
            m[2, 1] = BitConverter.ToSingle(bCamera, 28);
            m[2, 2] = BitConverter.ToSingle(bCamera, 32);

            return m;
        }
    }

    public static Vector2 WorldToScreen(float x, float y, float z)
    {
        var Projection = Matrix.PerspectiveFovRH(FOV * 0.5f, Aspect, NearClip, FarClip);

        var eye = new Vector3(X, Y, Z);
        var lookAt = new Vector3(X + Matrix[0, 0], Y + Matrix[0, 1], Z + Matrix[0, 2]);
        var up = new Vector3(0f, 0f, 1f);

        var View = Matrix.LookAtRH(eye, lookAt, up);
        var World = Matrix.Identity;

        var WorldPosition = new Vector3(x, y, z);

        var ScreenPosition = Vector3.Project(WorldPosition, 0f, 0f, WindowHelper.WindowWidth, WindowHelper.WindowHeight, NearClip, FarClip, World*View*Projection);
        return new Vector2(ScreenPosition.X, ScreenPosition.Y-20f);
...