首页
社区
课程
招聘
[求助]关于模仿11对战平台war3改键所有英雄技能全部qwer实现
发表于: 2013-9-4 23:59 20713

[求助]关于模仿11对战平台war3改键所有英雄技能全部qwer实现

2013-9-4 23:59
20713
各位好,我最近在做一个dota war3改建工具

目前我已经实现了自动进局域网等功能,我目前想实现所有英雄都是qwer,由于每个英雄的技能键位都是不一样的,所以无法从传统setkeyboard的思路去切入,而且war3好像也没有什么编程接口。

自己研究了下,我的想法是从游戏内存去查找当前英雄是哪一个来进行判断,这方面我不是很擅长,我想了解下,或者各位大神给我一些提示,怎么去从内存中获取当前英雄的数据。

我的作品:http://www.crsky.com/soft/45859.html

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 167
活跃值: (190)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
mh的源码里去翻吧  百度一大堆
2013-9-5 01:00
0
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
3
按键模拟鼠标点击可以不,定位技能栏坐标
2013-9-5 07:45
0
雪    币: 63
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
11平台应该是调用的War的按键CALL来实现的改建功能, 像楼主说的把英雄技能从 1 2 3 大招 按照 q w e r排列的话,  我觉得技能加点栏里面是个入口点
2013-9-5 15:04
0
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
#include <stdio.h>
#include <windows.h>

#include <TlHelp32.h>


DWORD GetWar3DllBase(char * dllName)
{
	DWORD dwRet = 0;
	MODULEENTRY32 me32;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 pe32= {0};
	pe32.dwSize = sizeof(PROCESSENTRY32);
	Process32First( hSnapshot, &pe32 );
    do
	{
        if ( lstrcmpi( pe32.szExeFile, "War3.exe" ) == 0 )
		{
            dwRet = pe32.th32ProcessID;
			//	War3Pid = dwRet;
            break;
		}
		printf("%s\n", pe32.szExeFile);
	} while ( Process32Next( hSnapshot, &pe32 ) );
    CloseHandle(hSnapshot);
	hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE,dwRet);
	me32.dwSize = sizeof(MODULEENTRY32);
	Module32First(hSnapshot,&me32);
	while(Module32Next(hSnapshot,&me32))
	{
		if(lstrcmpi (me32.szModule, dllName) ==0)
		{
			return (DWORD)me32.hModule;
		}
	}
	return 0;	
}

HANDLE GetWar3Handle()
{
	HWND hWar3 = FindWindow(NULL, "WarCraft III");
	DWORD dwPid = 0;
	GetWindowThreadProcessId(hWar3, &dwPid);
	if (dwPid)
	{
		HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, dwPid);
		return hProcess;
	}
	return NULL;
}

BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)//improve a privilege
{
	TOKEN_PRIVILEGES tp;
	LUID luid;
	
	if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
	{
		//	printf("\nLookupPrivilegeValue error:%d", GetLastError() ); 
		return false; 
	}
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	if (bEnablePrivilege)
		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	else
		tp.Privileges[0].Attributes = 0;
	// Enable the privilege or disable all privileges.
	AdjustTokenPrivileges(
		hToken, 
		FALSE, 
		&tp, 
		sizeof(TOKEN_PRIVILEGES), 
		(PTOKEN_PRIVILEGES) NULL, 
		(PDWORD) NULL); 
	// Call GetLastError to determine whether the function succeeded.
	if (GetLastError() != ERROR_SUCCESS) 
	{ 
		//printf("AdjustTokenPrivileges failed: %u\n", GetLastError() ); 
		return false; 
	} 
	return true;
}

BOOL EnableDebugPrivilege()
{
	BOOL bRet = FALSE;
	HANDLE hToken;
	if(OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken))
	{
		bRet = SetPrivilege(hToken,SE_DEBUG_NAME,true);
		CloseHandle (hToken);
	}
	return bRet;
}

HANDLE hWar3Process;
DWORD dwGameBase;
DWORD getDwordFromWar3(DWORD addr)
{
	DWORD tmp,ret;
	ReadProcessMemory(hWar3Process, (PVOID)addr, &ret, 4, &tmp);
	return ret;
}

//24b 0xACBDD8
//24e 0xACBDD8
//26 0xAB4F80
VOID getKeybdLayout(DWORD *key)
{
	key[0] = key[1] = key[2] = key[3] = 0;	
	DWORD eax = getDwordFromWar3(0xAB4F80+dwGameBase);
	if (eax)
	{
		eax += 0x3C8;
		eax = getDwordFromWar3(eax);
		if (eax)
		{
			DWORD ecx = eax + 0x154;
			DWORD edi = getDwordFromWar3(ecx) + 8;
			for (int i=0; i<4; i++)
			{
				eax = edi;
				for (int j=0; j<3; j++)
				{
					DWORD esi = getDwordFromWar3(eax);
					esi = getDwordFromWar3(esi+i*4);
					if (esi&&getDwordFromWar3(esi+0x94)&&getDwordFromWar3(esi+0x138))
					{
						DWORD ebp = getDwordFromWar3(esi+0x190);
						DWORD tmpkey = getDwordFromWar3(ebp+0x5AC);
						DWORD keyIndex = getDwordFromWar3(ebp+0x59C);//0x5ac-0x10
						DWORD keyType = getDwordFromWar3(ebp+0x59C+4);
						if (keyType==2 && keyIndex>=0 && keyIndex<=3)
						{
							key[keyIndex] = tmpkey;
						}
					}
					eax += 0x10;
				}
			}
		}
	}
}

void main()
{
	EnableDebugPrivilege();
	hWar3Process = GetWar3Handle();
	dwGameBase = GetWar3DllBase("game.dll");
	if (dwGameBase&&hWar3Process)
	{
		DWORD key[4];
		getKeybdLayout(key);
		for (int i=0; i<4; i++)
		{
			printf("Key_%d=%c\n", i, key[i]);
		}
		printf("\nok.\n");
	}
	else
	{
		printf("cannot find game.dll\n");
	}


	getchar();
}
2013-9-5 18:11
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
找到了,war3的内存地址:
http://blog.csdn.net/breeze356/article/details/5889415
不知你的  DWORD eax = getDwordFromWar3(0xAB4F80+dwGameBase); 0xAB4F80是什么地址
2013-9-7 16:03
0
雪    币: 396
活跃值: (838)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
1.24e读不到结果,读取的数据都是cccccccc,显然无效
2013-9-13 12:34
0
雪    币: 44
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
1、War3地图是一个512字节文件头 + MPQ包 的文件。
2、MPQ包里的war3map.w3u是单位数据表。
3、MPQ包里的war3map.w3a是技能表。

DOTA地图是经过SLK优化过的,而且是没有优化技能表,也就是地图包里存在war3map.w3a,所以可以先从内存中找出当前英雄的ID,这个ID是一个256进制的4字节字符串,然后用这个字符串去SLK数据表中匹配当前英雄所拥有的技能ID,也同样是一个256进制的4字节字符串,然后用这个ID去匹配War3map.w3a里的数据,每个技能都有4条数据,是技能图标的学习状态和普通状态的XY格子坐标,根据这个坐标你可以判定到QWER分别对应哪4个技能,然后用键盘钩子改键就可以了。

顺便,玩DOTA的人基本都已经习惯了默认按键的,甚至DOTA2里都用的传统按键,QWER改键对DOTA来说意义不大。
2013-9-25 17:44
0
雪    币: 200
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
exile #include &lt;stdio.h&gt; #include &lt;windows.h&gt; #include &lt;TlHelp32. ...
关于1.20和1.21的版本,我怎么也找不到类似下面的地址:
//24b  0xACBDD8
//24e  0xACBDD8
//26  0xAB4F80
2018-2-26 10:07
0
游客
登录 | 注册 方可回帖
返回
//