NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# C# .NET 매크로 프로그램 만들기. (멀티 다클라 매크로 중간 점검 및 테스트)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 엔지엠 매크로 6 버전에서 비활성 또는 활성 및 하드웨어(기계식) 모드에서 멀티 다클라 매크로를 제작하는데 복잡성을 줄이고, 좀 더 간단하게 처리할 수 있도록 많은 부분에서 개선이 되었습니다. 아무래도 엔지엠 초기부터 엔지엠 6까지는 한대의 컴퓨터에서 하나의 매크로만 동작시키는걸로 디자인을 하다보니 멀티 다클라 환경에서 처리가 쉽지 않았습니다. 엔지엠 6 에디터에서 멀티 다클라 매크로를 제작할 수 있지만, 싱글 매크로에서 기능을 붙이다보니 점점 복잡해져서 문제가 많았습니다.

     

    이번에 새롭게 디자인된 엔지엠 7(가칭)에서는 이 부분이 대폭 개선되었습니다. 디자인적으로도 멀티 다클라 환경에 맞게 최적화되었으며, 쉽고 직관적으로 스크립트를 제작할 수 있게 했습니다. 비활성 모드와 활성 모드(하드웨어 기계식 포함)에서 다클라 매크로를 쉽게 제작할 수 있도록 코딩을 해볼께요. 우선, 비활성 모드는 크게 2가지 부류로 나뉩니다. 첫번째는 핸들 수만큼 액션을 복사하는 것과 핸들 수만큼 스크립트를 복사하는 것입니다.

     

    활성 모드는 스크립트를 복사해서 전체 실행으로 동작시켜야 합니다. 비활성 모드는 창의 핸들 정보가 있기 때문에 자동으로 좌표를 시프트 시킬 수 있습니다. 하지만, 활성 모드는 창 핸들을 사용하지 않기 때문에 스크립트를 복사해서 창 크기만큼 오프셋을 설정해야 합니다. 오프셋도 쉽게 설정할 수 있도록 되어 있습니다.

     

    복습하는 차원에서 비활성 멀티 다클라 매크로를 테스트 해볼께요. 에디터를 실행하고, 그림판을 5개 실행합니다. 프로그램 제어 액션으로 창을 정렬했습니다.

    pmcmjWf.png

     

     

    창들이 이쁘게 정렬이 되었는데요. 여기서 각각의 그림판에 마우스 클릭과 드래그를 해볼께요. 우선 핸들 추가 액션으로 모든 그림판을 한번에 추가 해줍니다.

    UtjRtqo.png

     

     

    첫번째 그림판에 클릭할 좌표를 설정하고, 비동기로 실행될 수 있도록 입력 방식을 PostMessage로 변경하세요. 글로벌 설정을 해두면 모두 상속 받아서 처리되기 때문에 별도로 설정할 필요는 없습니다. 이 내용은 이전 글에서 확인할 수 있습니다.

    d2ekqwx.png

     

     

    마우스 드래그 액션은 엔지엠 7 버전에서 새롭게 추가된 액션입니다. 마우스 이동과는 다른 내용입니다. 마우스를 누르고, 이동한 후 땔 위치를 각각 설정해야 합니다.

    LobZinm.png

     

     

    완성된 매크로를 실행 해볼까요? 의도한대로 잘 동작하는군요.

     

     

    위의 테스트는 하나의 스크립트가 모든 클라이언트 프로그램에 동일하게 명령이 작동하는 방식입니다. 예를 들어서 게임 또는 텔레그램이나 카카오톡이 있다고 생각 해보세요. 이들은 창들마다 각각 다른 메세지가 올라오고 사냥터나 거래소 금액도 전부 다를겁니다. 이런 경우 하나의 클라이언트에서 이미지 인식 후 모두 동일한 조건으로 처리된다면 독립적으로 뭔가 처리할 수 없습니다.

     

    단순히 유튜브 동영상을 시청하다가 광고창이 뜨면 닫기를 누른다고 생각 해보세요. 이 때 광고창이 뜰수도 있고 안뜰수도 있습니다. 로직은 그대로 가져가면서 각각 별도의 스크립트인것처럼 독립적으로 동작시키려면 핸들 추가 액션에서 비동기 옵션을 켜주기만 하면 됩니다. 아주 간단하죠? 시각적으로 확인할 수 있는 로직으로 스크립트를 만들지는 않았기 때문에 하단 출력창의 로그를 확인해야 합니다. 비동기 옵션을 True로 변경하면 핸들 수 만큼 가상 스크립트를 만들어서 독립적으로 실행됩니다.

     

    매크로를 실행하면 아래와 같이 테스트는 동일합니다. 하지만, 하단의 출력창을 확인해보면 로그가 달라진걸 확인할 수 있을겁니다.

     

     

    각각의 프로그램 핸들 값이 스크립트명 뒤에 붙어서 새로운 스크립트를 자동 생성합니다. 아래는 그림판 5개의 가상 스크립트가 자동으로 생성되서 실행된 후 완료된 상태입니다. 참고로, 가상 스크립트는 메모리에서 만들어지고 완료되면 사라지기 때문에 물리적인 파일을 생성했던 이전 버전보다 퍼포먼스가 드라마틱하게 향상되었습니다. 그리고, 파일 IO가 없기 때문에 스레드로부터 안전합니다.

    qKORjIc.png

     

     

    이번에는 활성 모드(하드웨어, 기계식, 소프트웨어 신호등등...)에서 테스트를 해볼께요. 비활성 모드에서 마우스와 키보드 신호를 사용할 수 없다면 활성 모드로 매크로를 만들어야 합니다. 하지만, 활성모드라고 해서 멀티 다클라를 할 수 없는건 아닙니다. 대부분의 비즈니스 로직과 이미지 분석, 문자와 숫자 인식등등은 멀티로 실행되어도 문제가 안됩니다. 하지만, 물리적으로 마우스와 키보드가 하나이기 때문에 비활성 모드처럼 마우스 클릭이 동시에 입력되면 문제가 발생합니다.

     

    예를 들어서 A 그림판에 마우스 클릭(마우스 다운과 업)이 발생할 때 다른 그림판에서 클릭이 동시에 발생하면 A그림판에서 마우스 다운, B그림판에서 마우스 다운, A그림판에서 마우스 업, B그림판에서 마우스업이 될 수 있습니다. 마우스 다운과 업은 한세트인데요. 이 사이에 다른 마우스 다운과 업 신호가 간섭을 일으키면 드래그와 같은 효과가 발생하게 됩니다. 다운, 업, 다운, 업과 같이 정상적으로 동작할수도 있지만, 다운, 다운, 업, 업이 될수도 있습니다.

     

    이 문제를 해결하려면 마우스 클릭의 다운과 업이 처리 완료된 후 다른 신호가 처리하도록 동기화해야 합니다. 마우스 클릭이 연속 10번 발생한다면 1번이 처리될 때까지 나머지는 기다렸다가 1번이 끝나면 순서대로 처리하면 됩니다. 수백번, 수천번의 클릭이 발생하더라도 거의 순간이기 때문에 밀리거나 그럴일은 없을겁니다. 이미지 서치나 이미지 매치를 하나라도 처리하는 시간에 대기하고 있던 명령들이 순차적으로 처리되기 때문에 컴퓨터의 성능을 최대한으로 끌어올려서 사용할 수 있습니다.

     

    스크립트를 복사해서 총 5개를 만들었습니다.

    CrCHUpj.png

     

     

    각각의 스크립트에 오프셋을 추가한 후 창 위치만큼 오프셋 값을 설정해줍니다. 첫번째 스크립트는 안해도 되고, 두번째 스크립트부터 그림판의 위치 값을 오프셋으로 입력해야 합니다. 그림판 창 크기가 500, 400이기 때문에 우측으로 500씩 더하고, 하단으로는 400을 더해주면 됩니다.

    6d3fLT6.png

     

     

    스크립트 실행이 아닌 스크립트 전체 실행을 클릭하세요. 아래 동영상과 같이 정상적으로 처리되지 않습니다. 순식간에 모든 스크립트의 명령을 처리하려다보니 마우스 동작이 꼬여서 다운과 업이 상쇄되고 오프셋도 넘어가지 못해서 좌표도 뒤죽박죽이 되어 버렸습니다.

     

     

    이 문제를 해결하려면 하나의 마우스를 여러명이서 사용할 수 있게 동기화 시켜야 합니다. 대부분의 비즈니스 로직은 비동기적으로 각자 처리할 수 있습니다. 하지만, 마우스와 키보드처럼 장치 입력은 순서대로 하나씩 처리해야 합니다. 비활성 모드만큼 효율적이진 않지만 컴퓨터 1대에 하나의 스크립트만 돌리는 것보다는 훨씬 더 효율적으로 작업을 진행할 수 있습니다.

     

    옵션에서 마우스 동기화에 체크하고 저장하세요.

    WOxqAOS.png

     

     

    매크로를 다시 전체 실행 하세요. 이제는 정상적으로 잘 동작하는군요.

     

     

    이 기능을 구현하기 위해서 옵션에 마우스와 키보드 동기화 컨트롤을 하나 제작했습니다.

    using Ai.Common.Client.Interface;
    
    namespace Ai.Common.Client.OptionItem
    {
        public partial class EditorSyncItem : UserControl, ISyncItem
        {
            public bool UseMouseSync { get { return this.chkMouseSync.Checked; } set { this.chkMouseSync.Checked = value; } }
    
            public bool UseKeyboardSync { get { return this.chkKeyboardSync.Checked; } set { this.chkKeyboardSync.Checked = value; } }
    
            public EditorSyncItem()
            {
                InitializeComponent();
    
                pnlHelper.BackgroundImage = (Image)Ai.ResourceManager.ImageResource.Instance.GetObject("question");
                pnlHelper.BackgroundImageLayout = ImageLayout.Center;
            }
        }
    }

     

    이 콘트롤은 OptionModel과 동기화되어야 하므로, 아래와 같이 컨트롤의 속성을 동일하게 만들어줘야 합니다.

    /// <summary>
    /// 멀티 스레딩 환경에서 마우스 동기화를 사용합니다.
    /// </summary>
    public bool UseMouseSync { get; set; }
    
    /// <summary>
    /// 멀티 스레딩 환경에서 키보드 동기화를 사용합니다.
    /// </summary>
    public bool UseKeyboardSync { get; set; }

     

    IClient 인터페이스에서 옵션이 변경되었을 때 갱신될 수 있도록 메소드를 하나 추가해줍니다.

    void OptionReload();

     

    옵션이 변경되면 스크립트에서 변경된 설정을 가져와서 셋팅한 후 다시 실행되도록 구현해야 합니다. 이 부분은 플레이어에서 처리하면 될거 같습니다. 생각해보면, 플레이어마다 각각 설정을 해보려고 했으나, 플레이어는 스크립트가 실행되는 시점에 동적으로 만들어지기 때문에 미리 정보를 저장해둘 수 없습니다. 그리고, 어떤 플레이어에서 해당 값을 가져와야 하는지도 알 수 없기 때문에 글로벌하게 클라이언트에 저장하는게 편리할 듯 합니다.

     

    구조적으로 변경이 필요할수도 있겠지만, 현재로써는 각각의 플레이어가 따로 적용될 필요가 있을지 의문이네요. 일단은 이렇게 구조를 만들어두고 나중에 개선할 수 있는지는 따져봐야겠습니다. 활성과 비활성을 각각 설정해서 사용한다면... 이런 시나리오가 있을지는 모르겠네요. 아무튼, 이건 나중에 생각하기로 합시다.

     

    이제 마우스와 키보드에 동기화할 루틴 위에 아래 조건을 추가 해줍니다.

    bool locked = false;
    if (player.Manager.UseMouseSync)
    {
        Monitor.Enter(player.Manager.Lock);
        locked = true;
    }

     

    루틴에 락이 걸리면 해제를 해야 하는데요. 여기서 약간의 성능 하락이 발생합니다. 약간이라고는 했지만, 미미한 수준이고 측정 불가능할만큼 작은 시간입니다.

    try
    {
        // do something
    }
    finally
    {
        if (locked) Monitor.Exit(player.Manager.Lock);
    }

     

    이렇게해서 멀티 다클라 환경에서 매크로를 제작할 때 어떻게 만들어야 하는지 알아봤습니다. 전체적인 코드는 없고, 대략적인 디자인과 구조를 설명하는데 중점을 두었습니다. 코딩이야 아무나 할 수 있는 부분이라서요. 하지만, 디자인과 구조는 꾸준히 해오지 않았다면 어려운 부분입니다. 아마도, 코드를 여러번 갈아엎어야 할수도 있습니다. 그래서, 가능하면 머리속에 생각한 것들을 종이로 옮겨보고, 다시한번 체크한다면 좀 더 괜찮은 디자인이 나올수도 있을겁니다. 머리속으로 시뮬레이션을 돌려보면서 방법을 찾아야겠죠^^;

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.