发一个大话西游2解决模拟移动鼠标会偏差的代码

运行大话西游2游戏,模拟鼠标操作的话会发现游戏窗口里的光标跟系统光标不一致

而且每次的距离差都不一样,开着QQ在游戏窗口里ctrl+alt+a截图就可以看到两个光标的距离差了。

另外,游戏里的光标不是硬件光杯。

这里的方法是设定一个精确值,根据每次的移动鼠标的差值来调整游戏里的光标位置

首先要获取游戏里的光标的位置,有两种方法:

1、因为游戏里的光标不是硬件光标,所以图像是可以获取到的,可以用图像对比的方试获取到游戏里的光标位置,但是这个游戏里的光标是动态的,这里需要先固定光标。

   游戏光标资源在gires.wdf这个文件,用a-wdf.exe解压出来之后,鼠标光标在0016号.was文件,改成一帧的tga再重新打包就可以了,进入游戏后发现光标不动了,可以用图像对比来找游戏光标位置了,需要注意的是游戏里还有一种手式的静态光标,需要两个都找一找,才不会漏。

   这种方式不好,因为鼠标移到游戏窗口最右边的时候会发现光标找不到了,需要调整多次而且不稳定。

2、内存方式(我用这种方法)

   这种方法相对比较简单,原来猜想里外光标位置不一致,游戏里应该会保存自己的光标位置才对,用CE搜到了。然后找基址,

最后定位在  x=[[5e123c]+0a8b4] ; y=[[5e123c]+0a8b8]

找到游戏光标位置之后就可以根据系统鼠标位置调整了,以下为代码

void SetDhxyCursorPos( POINT & pt )
{
	POINT GamePos; //游戏里的鼠标位置
	POINT SysPos;  //系统的鼠标位置
	POINT DestPos; //目标鼠标位置
	POINT LastPos; //调整的上一个位置
	int   ix,iy;
	ULONG uSleeped = 0;

	DebugPrintA( _T("目标点[%d,%d]"),pt.x,pt.y );


	//
	// 初始化把鼠标移到目标点
	//
	MovePos.x = DestPos.x = pt.x;
	MovePos.y = DestPos.y = pt.y;
	SetCursorPos( DestPos.x,DestPos.y );
	Sleep( 100 );

	//
	// 调整移偏了的鼠标
	//
	do 
	{

		//
		//获取大话西游光标位置
		//
		while( TRUE )
		{
			GamePos.x = 0;
			GamePos.y = 0;
			if( FALSE == GetDhxyCursorPos( GamePos ) ) {
				//
				// 光标偏到窗口外,无法获取
				// 把鼠标调整回原点
				//
				DebugPrintA( _T("找不到光标,调整回原点") );
			}
			else {
				//
				break;
			}
		}

		GetCursorPos( &SysPos );

		DebugPrintA( _T("游戏光标[%d,%d]"),GamePos.x,GamePos.y );
		DebugPrintA( _T("系统光标[%d,%d]"),SysPos.x,SysPos.y );

		//
		// 计算差值
		//
		ix = (int)DestPos.x - (int)GamePos.x;
		iy = (int)DestPos.y - (int)GamePos.y;

		DebugPrintA( _T("差值[%d,%d]"),ix,iy );

		// 
		// 精确差值为10
		//
		if( abs(ix)<5 && abs(iy)<5 ) {
			break;
		}

		//保存上一个位置
		LastPos.x = pt.x;
		LastPos.y = pt.y;

		//x
		if( ix < 0 ) {
			//光标移太过去的情况
			pt.x -= abs(ix);
		}
		else {
			//光标移不够的情况
			pt.x += abs(ix);
		}
		//y
		if( iy < 0 ) {
			//光标移太下面的情况
			pt.y -= abs(iy);
		}
		else {
			//光标移太上面的情况
			pt.y += abs(iy);
		}

		//处理负坐标
		if( pt.x < 0 ) {
			pt.x = abs(pt.x);
		}
		if( pt.y < 0 ) {
			pt.y = abs(pt.y);
		}

		DebugPrintA( _T("调整坐标为[%d,%d]"),pt.x,pt.y );

		//
		// 新的调整点是否在游戏窗口内
		//
		//移动新的位置
		SetCursorPos( pt.x,pt.y );

		

		//延时
		Sleep( 200 );

		//
		// 加延时,以免死循环在这里
		//
		uSleeped ++;
		if( uSleeped >= 20 ) {
			DebugPrintA( _T("移动鼠标失败") );
			break;
		}


	} while ( TRUE );
}
完!
原文地址:https://www.cnblogs.com/dcai/p/1743669.html