среда, 22 января 2014 г.

WoT Marker (поддержите огнем по.... )

Играя в ротных боях и стреляя по фокусу или маркеру (кому как удобно) зачастую сам не успеваешь или забываешь или не попадаешь по кнопке маркера (по умолчанию "T"). А маркер ставить надо:
во 1ых командир видит кто куда стреляет
во 2ых маркер должен гореть пока противник жив

Об этом конечно можно поспорить, мол чат забивается итд, 5ое, 10ое речь не об этом. В некоторых отладочных случаях может понадобиться ставить маркер вместе с выстрелом. Настроить это обычным способом не получится (Клиент игры не дает устанавливать выстрел и маркер на LMB), через изменение XML файла настроек изменить можно:
Файл:
 %appdata%\Wargaming.net\WorldOfTanks\preferences.xml
Секции:
<CMD_CM_SHOOT> <fireKey> KEY_LEFTMOUSE </fireKey> <satelliteKeys> </satelliteKeys></CMD_CM_SHOOT>
<CMD_CHAT_SHORTCUT_ATTACK>
<fireKey> KEY_T </fireKey>
<satelliteKeys> </satelliteKeys>
</CMD_CHAT_SHORTCUT_ATTACK>
 но не работает... как же быть?

лично я сделал следующее:
установил виндовый хук на левую кнопку мыши и в callback функции отправляю окну игры оконное сообщение (PostMessageA) с нажатием на кнопку маркера которая настроена в клиенте. Таким не хитрым образом вместе с выстрелом одновременно ставится маркер.

Код:

HookDLL.cpp
#####################################################################
#include "stdafx.h"
#include "HookDLL.h"

#pragma data_seg(".Segment")
HWND hWndServer = NULL;
UINT UWM_MOUSELBUTTONDOWN;
unsigned long iMessageDown=0, iMessageUp=0, iWparamDown=0, iLparamDown=0, iWparamUp=0, iLparamUp=0;
#pragma data_seg()
#pragma comment(linker, "/section:.Segment,rws")

HINSTANCE hInst;

HHOOK hook;

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
switch( ul_reason_for_call )
    {
case DLL_PROCESS_ATTACH:
hInst = hModule;
UWM_MOUSELBUTTONDOWN = ::RegisterWindowMessage(UWM_MOUSELBUTTONDOWN_MSG);
break;
default:
break;
}
    return TRUE;

}


static LRESULT CALLBACK MouseMsgProc(UINT nCode, WPARAM wParam, LPARAM lParam);


__declspec(dllexport)  BOOL InstallHook( HWND hWndParent, unsigned long MESSAGEDOWN, unsigned long MESSAGEUP, unsigned long WPARAMDOWN, unsigned long LPARAMDOWN, unsigned long WPARAMUP, unsigned long LPARAMUP )
{

if(hWndServer != NULL)
return FALSE; // already hooked!
hook = SetWindowsHookEx( WH_GETMESSAGE, (HOOKPROC)MouseMsgProc, hInst, 0);
if(hook != NULL)
{
iMessageDown = MESSAGEDOWN;
iMessageUp = MESSAGEUP;
iWparamDown = WPARAMDOWN;
iLparamDown = LPARAMDOWN;
iWparamUp = WPARAMUP;
iLparamUp = LPARAMUP;

hWndServer = hWndParent;
return TRUE;
}
return FALSE;
}

__declspec(dllexport) BOOL UnInstallHook( HWND hWndParent )
{
if(hWndParent != hWndServer || hWndParent == NULL)
return FALSE;
     BOOL unhooked = UnhookWindowsHookEx(hook);
     if(unhooked)
hWndServer = NULL;
     return unhooked;
return TRUE;
}


static LRESULT CALLBACK MouseMsgProc(UINT nCode, WPARAM wParam, LPARAM lParam)
{

if(nCode < 0)
{
CallNextHookEx(hook, nCode, wParam, lParam);
return 0;
}
LPMSG msg = (LPMSG)lParam;
switch( msg->message  )
{

case WM_LBUTTONDOWN:
::PostMessageA(hWndServer, iMessageDown, iWparamDown, iLparamDown);
::PostMessageA(hWndServer,  iMessageUp, iWparamUp, iLparamUp);

break;
case WM_NCLBUTTONDOWN:
::PostMessageA(hWndServer, iMessageDown, iWparamDown, iLparamDown);
::PostMessageA(hWndServer,  iMessageUp, iWparamUp, iLparamUp);
break;

default:
break;
}
return CallNextHookEx(hook, nCode, wParam, lParam);
}




HookDLL.h
############################################################
#ifndef _MOUSE_EVENT_RECORD_H_
#define _MOUSE_EVENT_RECORD_H_
#define LIBSPEC __declspec(dllexport)

   LIBSPEC BOOL InstallHook( HWND hWndParent, unsigned long MESSAGEDOWN, unsigned long MESSAGEUP, unsigned long WPARAMDOWN, unsigned long LPARAMDOWN, unsigned long WPARAMUP, unsigned long LPARAMUP );
   LIBSPEC BOOL UnInstallHook(HWND hWnd);
#undef LIBSPEC

#define UWM_MOUSELBUTTONDOWN_MSG ( L"UWM_MOUSELBUTTONDOWN_USER_MSG" )

#endif




WoTAutoMarker.cpp
###############################################################

#include "stdafx.h"
#include "Windows.h"
#include "conio.h"
#include "HookDLL.h"
#include <iostream>
#include <fstream>
#include <string>

#pragma comment(lib, "HookDLL.lib")

int _tmain(int argc, _TCHAR* argv[])
{
  unsigned long MESSAGEDOWN;
  unsigned long MESSAGEUP;
  unsigned long WPARAMDOWN;
  unsigned long LPARAMDOWN;
  unsigned long WPARAMUP;
  unsigned long LPARAMUP;
  std::string line;

  std::ifstream fconfig ("config.txt");
  if (fconfig.is_open())
  {
    std::getline (fconfig, line);
    MESSAGEDOWN = stoul(line);
std::cout << "MESSAGEDOWN: " << line << "\n";
std::getline (fconfig, line);
    MESSAGEUP = stoul(line);
std::cout << "MESSAGEUP: " << line << "\n";

std::getline (fconfig, line);
    WPARAMDOWN = stoul(line);
std::cout << "WPARAMDOWN: " << line << "\n";

std::getline (fconfig, line);
    LPARAMDOWN = stoul(line);
std::cout << "LPARAMDOWN: " << line << "\n";

std::getline (fconfig, line);
    WPARAMUP = stoul(line);
std::cout << "WPARAMUP: " << line << "\n";

std::getline (fconfig, line);
    LPARAMUP = stoul(line);
std::cout << "LPARAMUP: " << line << "\n";
fconfig.close();
  }

  else {
 std::cout << "Unable to open config.txt file"; 
 getch();
 return 0;
  }



HWND hWnd = ::FindWindowEx(NULL,NULL,L"App", NULL);
printf("hWnd: %Xh\n", hWnd);
if ((int)hWnd == 0) {
printf("please launch WORLDOFTANKS.EXE and try again...\nAny key to exit");
getch();
return 0;
}

if (InstallHook(hWnd, MESSAGEDOWN, MESSAGEUP, WPARAMDOWN, LPARAMDOWN, WPARAMUP, LPARAMUP))
printf("mouse hook install\n");
else
printf("mouse hook NOT install. try again later...\n");
printf("press any key to exit after game.\n");
getch();

UnInstallHook(hWnd);
    return 0;
 
}

Видео о там как это работает
Для тех кому лень возиться с компилятором:
скачать