ITPub博客

首页 > 数据库 > 数据库开发技术 > 硬核教程 - 使用Rust编写网游FPS外挂辅助

硬核教程 - 使用Rust编写网游FPS外挂辅助

原创 数据库开发技术 作者:Rust语言中文社区 时间:2020-07-13 22:02:58 0 删除 编辑
优势:Rust没有GC 效率和C++一样快 本贴子主要用于观摩和学习调用windows api,禁止用于某些用途
目标 - 扫描屏幕敌人出现红色的名字,达到自动开枪的目的。效果 - 爆破模式和狙击枪使用的时候 瞬间秒杀敌人。程序的反应时间为1秒/60fps=0.01秒。这性能保证了 只要准心略过敌人身体,永远都是你先开第一枪
具体步骤:1屏幕截BitMap图片数据(本教程屏幕尺寸为1920*1080.具体屏幕尺寸需要自行测量),找图找色,找名字颜色 2根据扫描到的RGB颜色值矩阵找红色+黑色描边名字 3模拟鼠标按下和抬起
用到的库:
winapi-rs
用到的windows API:
mouse_event //模拟鼠标点击 
CreateCompatibleBitmap //创建位图 
SelectObject BitBlt GetDIBits //取得屏幕图片 
DeleteDC ReleaseDC //释放句柄 DeleteObject
#[cfg(windows)]
extern crate winapi;

use std::ffi::CString;
use std::io::{Bytes, Error};
use std::ptr::null_mut;
use std::thread::sleep;
use std::time::SystemTime;

use winapi::_core::mem::size_of;
use winapi::_core::str::Chars;
use winapi::_core::time::Duration;
use winapi::ctypes::{c_char, c_void};
use winapi::shared::minwindef::BYTE;
use winapi::shared::windef::{HBITMAP, HBITMAP__, HGDIOBJ, HWND, POINT, RECT, SIZE};
use winapi::um::errhandlingapi::GetLastError;
use winapi::um::wingdi;
use winapi::um::wingdi::{BI_RGB, BitBlt, BITMAPINFO, BITMAPINFOHEADER, CreateCompatibleBitmap, CreateCompatibleDC, DeleteDC, DeleteObject, DIB_RGB_COLORS, GetBValue, GetDIBits, GetGValue, GetPixel, GetRValue, GetTextColor, RGBQUAD, SelectObject, SRCCOPY};
use winapi::um::winuser::{GetCursorPos, GetDC, GetDesktopWindow, GetTopWindow, GetWindowDC, GetWindowRect, mouse_event, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, ReleaseDC};

use crate::util::{click_mouse_event, click_send_input, is_red, pixel_to_rgb, rgb_is_black, rgb_is_red, write_file};

pub mod util;


/// step: 步长
#[cfg(windows)]
unsafe fn find_color(left: u32, top: u32, right: u32, bottom: u32, step: usize) -> bool {
let h_screen_dc = GetDC(null_mut());//获得屏幕的HDC
let mem_dc = CreateCompatibleDC(h_screen_dc);//创建一个内存中的DC
let mut rect: RECT = RECT {
left: left as i32,
top: top as i32,
right: right as i32,
bottom: bottom as i32,
};
//获取屏幕尺寸
// GetWindowRect(h_desk_top_wnd, &mut rect);
let mut screensize = SIZE { cx: 0, cy: 0 };
screensize.cx = rect.right - rect.left;
screensize.cy = rect.bottom - rect.top;

let mut h_bitmap: HBITMAP;
h_bitmap = CreateCompatibleBitmap(h_screen_dc, screensize.cx, screensize.cy);
let h_old_bmp = SelectObject(mem_dc, h_bitmap as HGDIOBJ);
let bit_blt_success = BitBlt(mem_dc, 0, 0, screensize.cx, screensize.cy, h_screen_dc, rect.left, rect.top, SRCCOPY);
if bit_blt_success as i32 == 0 {
//注意释放资源
DeleteDC(h_screen_dc);
DeleteDC(mem_dc);
ReleaseDC(h_screen_dc as HWND, mem_dc);
ReleaseDC(null_mut(), h_screen_dc);
DeleteObject(mem_dc as HGDIOBJ);
DeleteObject(h_old_bmp);
DeleteObject(h_bitmap as HGDIOBJ);
return false;
}
let mut bit_info: BITMAPINFO = BITMAPINFO {
bmiHeader: BITMAPINFOHEADER {
biSize: size_of::<BITMAPINFOHEADER>() as u32,
biWidth: screensize.cx,
biHeight: screensize.cy,
biPlanes: 1,
biBitCount: 32,
biCompression: BI_RGB,
biSizeImage: 0,
biXPelsPerMeter: 0,
biYPelsPerMeter: 0,
biClrUsed: 0,
biClrImportant: 0,
},
bmiColors: [RGBQUAD {
rgbBlue: 0,
rgbGreen: 0,
rgbRed: 0,
rgbReserved: 0,
}; 1],
};

let mut is_find_color = false;

let mut result = 0;
//第一次调用GetDIBits获得图片的大小
result = GetDIBits(mem_dc, h_bitmap, 0, screensize.cy as u32, null_mut(), &mut bit_info, DIB_RGB_COLORS);
if result != 0 {
//第二次调用GetDIBits取图片流数据
// 位图信息及调色板大小
let info_size = bit_info.bmiHeader.biSize + bit_info.bmiHeader.biClrUsed * size_of::<RGBQUAD>() as u32;
//缓冲区大小
let size: usize = bit_info.bmiHeader.biSizeImage as usize + info_size as usize;

//缓存
let mut buffer = vec![0u8; size];
let ptr = buffer.as_mut_ptr().cast();
result = GetDIBits(mem_dc, h_bitmap, 0, screensize.cy as u32, ptr, &mut bit_info, DIB_RGB_COLORS);

if result == 0 {
println!("2设置图片信息出错");
is_find_color = false;
}else{
let mut have_black = false;
let mut last_i = 0;

let len = size / 4;
for i in 0..len {
if step != 0 && i % step != 0 {
continue;
}
let rv = buffer[(size - i * 4) - 2] as i32;
let gv = buffer[(size - i * 4) - 3] as i32;
let bv = buffer[(size - i * 4) - 4] as i32;

if rgb_is_black(rv, gv, bv) {
have_black = true;
last_i = i;
}

if rgb_is_red(rv, gv, bv) && have_black && last_i + 1 == i {
//println!("find red r:{},g:{},b:{}", rv, gv, bv);
is_find_color = true;
break;
}
}
}
} else {
let e = GetLastError();
println!("1设置图片信息出错,code: {}", e);
}
//gc
DeleteDC(h_screen_dc);
DeleteDC(mem_dc);
ReleaseDC(h_screen_dc as HWND, mem_dc);
ReleaseDC(null_mut(), h_screen_dc);
DeleteObject(mem_dc as HGDIOBJ);
DeleteObject(h_old_bmp);
DeleteObject(h_bitmap as HGDIOBJ);
return is_find_color;
}


#[cfg(windows)]
unsafe fn print_message() {
// let pixel= GetPixel(null_mut(),0,512);
// println!("{}",pixel);
let mut p = POINT {
x: 0,
y: 0,
};
let hDeskTopWnd = GetDesktopWindow();//获得屏幕的HWND
let hScreenDC = GetDC(hDeskTopWnd);//获得屏幕的HDC
loop {
GetCursorPos(&mut p);
println!("point: {},{}", &p.x, &p.y);

let pixel = GetPixel(hScreenDC, p.x, p.y);
println!("pixel: {}", pixel);

pixel_to_rgb(pixel as u32);

sleep(Duration::from_secs(1));
}
}



unsafe fn loop_find_color() {
loop {
find_color(0, 0, 10, 100, 0);
}
}


unsafe fn loop_find_cf_color() {
println!("done");
loop {
//let find = find_color(0, 0, 10, 100, 0);;
let find = find_color(918, 570, 918 + 100, 570 + 57, 0);
if find {
click_mouse_event(0, 0);
println!("click");
}
}
}

fn main() {
println!("now start!");
//bench_rate();
unsafe { loop_find_cf_color(); }
}

封装util.rs

use std::fs::File;
use std::io::Write;
use std::thread::sleep;
use std::time::Duration;

use winapi::_core::mem::size_of;
use winapi::um::winuser::{GetCursorPos, GetDC, INPUT, INPUT_MOUSE, INPUT_u, mouse_event, MOUSEEVENTF_ABSOLUTE, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MOVE, MOUSEINPUT, SendInput};

pub unsafe fn click_send_input(dx: u32, dy: u32) {
let mut input = INPUT { type_: INPUT_MOUSE, u: INPUT_u::default() };
let mi = input.u.mi_mut();
mi.dx = 0;
mi.dy = 0;
mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &mut input, size_of::<INPUT>() as i32);
sleep(Duration::from_millis(50));

let mut input = INPUT { type_: INPUT_MOUSE, u: INPUT_u::default() };
let mi = input.u.mi_mut();
mi.dx = 0;
mi.dy = 0;
mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &mut input, size_of::<INPUT>() as i32);
sleep(Duration::from_millis(100));
}

pub unsafe fn click_mouse_event(dx: u32, dy: u32) {
mouse_event(MOUSEEVENTF_LEFTDOWN, dx, dy, 0, 0);
sleep(Duration::from_millis(50));
mouse_event(MOUSEEVENTF_LEFTUP, dx, dy, 0, 0);
}

pub fn pixel_to_rgb(pixel: u32) -> (i32, i32, i32) {
let rv = pixel & 0xFF;
let gv = (pixel & 0xFF00) / 256;
let bv = (pixel & 0xFF0000) / 65536;

let rv = rv as i32;
let gv = gv as i32;
let bv = bv as i32;

//mouse::click(p.x as u32,p.y as u32);
rgb_is_red(rv, gv, bv);
return (rv, gv, bv);
}

pub fn rgb_is_red(rv: i32, gv: i32, bv: i32) -> bool {
if rv >= 140 && gv <= 70 && bv <= 70 {
// println!("Is Red r:{},g:{},b:{}", rv, gv, bv);
return true;
} else {
// println!("Not Red R_:{},G_:{},B_:{}", rv, gv, bv);
return false;
}
}

pub fn rgb_is_black(rv: i32, gv: i32, bv: i32) -> bool {
if rv == 0 && gv == 0 && bv== 0 {
// println!("Is Red r:{},g:{},b:{}", rv, gv, bv);
return true;
} else {
// println!("Not Red R_:{},G_:{},B_:{}", rv, gv, bv);
return false;
}
}


pub fn is_red(rv: i32, gv: i32, bv: i32, r_diff: i32, gb_diff: i32) -> bool {
let rg: i32 = (rv - gv);
let rb: i32 = (rv - bv);
let gb: i32 = (gv - bv);
if rg.abs() >= r_diff && rb.abs() >= r_diff && gb.abs() <= gb_diff {
return true;
}
return false;
}

原文作者:Rust语言中文社区;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2020-06-11

  • 博文量
    1769
  • 访问量
    718745