nezha/src/pokemmo/pokemmo.rs

233 lines
9.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#[cfg(feature = "pokemmo")]
pub mod pokemmo {
use std::thread;
use std::time::Duration;
use enigo::Key;
use enigo::Key::{N, V};
use image::{DynamicImage, RgbaImage};
use image::io::Reader as ImageReader;
use log::{error, info, trace};
use rand::thread_rng;
use rusty_tesseract::Image;
use screenshots::Compression;
use crate::joystick::joystick::joystick::{move_once_by_mode, MoveMode, quick_press};
use crate::ocr::ocr::ocr::find_string_in_image;
use crate::pokemmo::const_value::pokemmo_const_value::{BUTTON_HL_1, BUTTON_HL_2, BUTTON_HL_3, BUTTON_HL_4, GROUP_5_1, GROUP_5_2, GROUP_5_3, GROUP_5_4, GROUP_5_5, LAST_TEXT_AREA, LOGO, PokemmoStatus, SINGLE_BATTLE, TEMP_BATTLE_TEXT_AREA, TEXT_AREA};
use crate::pokemmo::const_value::pokemmo_const_value::PokemmoStatus::{Free, InBattle, LoadBattle, MeetTarget, Running};
use crate::screen::screen::screen::{Area, screen_shot};
// 单遇闪光
pub fn single_meet_shiny(key_words: &Vec<String>) {
let mut status = PokemmoStatus::Free;
let move_mode = MoveMode::HORIZONTAL;
let mut move_index = 0_usize;
let mut meet_pokemmo: String = String::new();
loop {
trace!("当前状态:{:?}",status);
match status {
PokemmoStatus::MeetTarget => {
return;
}
PokemmoStatus::Free => {
trace!("自由状态,移动一步");
move_once_by_mode(&move_mode, move_index);
move_index = move_index + 1;
let text = get_last_string();
trace!("查询战斗文字 : {}",text);
if text.contains("wild") || text.contains("sent") {
info!("遇怪:{}.",text);
meet_pokemmo = text.clone();
status = LoadBattle;
}else {
let temp_battle = read_area(TEMP_BATTLE_TEXT_AREA);
if temp_battle.contains("fight") || temp_battle.contains("run"){
status = LoadBattle;
}
}
}
PokemmoStatus::LoadBattle => {
info!("进入加载动画");
let mut btn_index = None;
while btn_index == None {
trace!("等待按钮加载");
let est_index = get_choose_btn();
if est_index.is_some() {
btn_index = est_index;
status = InBattle;
}
thread::sleep(Duration::from_millis(100));
}
}
PokemmoStatus::InBattle => {
trace!("检查遇怪种类..");
let text = get_text_list();
let filter_text: Vec<String> = text.into_iter().filter(|x| x.contains("wild")).collect();
if filter_text.is_empty() {
error!("遇怪错误!");
return;
}
let filter_size = filter_text.len();
let pokemon_text = filter_text[filter_size - 1].clone();
if pokemon_text.contains("horde") {
info!("遇见怪群");
let five_names = read_group_5();
for name in five_names {
for key_word in key_words {
if name.contains(key_word) {
status = MeetTarget;
return;
}
}
}
} else {
let name = read_area(SINGLE_BATTLE);
info!("单遇:{}",name);
for key_word in key_words {
if name.contains(key_word) || meet_pokemmo.contains(key_word) {
info!("遇见{}",key_word);
status = MeetTarget;
return;
}
}
}
// 进入招式界面
status = PokemmoStatus::Running
}
PokemmoStatus::Running => {
thread::sleep(Duration::from_micros(100));
quick_press(Key::Layout('l'));
thread::sleep(Duration::from_micros(100));
quick_press(Key::Layout('k'));
thread::sleep(Duration::from_micros(100));
let mut est_index = get_choose_btn();
while est_index.is_none() || est_index.unwrap() != 3 {
quick_press(Key::Layout('l'));
quick_press(Key::Layout('k'));
trace!("尝试获取激活按钮");
est_index = get_choose_btn();
}
quick_press(Key::Layout('z'));
thread::sleep(Duration::from_micros(100));
status = PokemmoStatus::CheckRun;
}
PokemmoStatus::CheckRun => {
let mut last_word = get_last_string();
// 读取十次后默认成功
let mut times = 0_usize;
while !last_word.contains("escaped")
&& !last_word.contains("中逃跑")
&& !last_word.contains("不能跑")
&& times < 10{
trace!("读取逃跑文档 {}",last_word);
last_word = get_last_string();
thread::sleep(Duration::from_millis(200));
times = times + 1;
}
if last_word.contains("escaped") || last_word.contains("safely") {
trace!("逃跑成功.");
status = Free;
} else {
trace!("逃跑失败");
status = Free;
}
}
}
}
}
pub fn get_text_list() -> Vec<String> {
let text_image = read_area(TEXT_AREA);
let text_list: Vec<String> = text_image.split("\r\n").filter(|x| !x.is_empty()).map(|x| String::from(x)).collect();
return text_list;
}
pub fn get_last_string() -> String {
let text_image = read_area(LAST_TEXT_AREA);
return text_image;
}
pub(crate) fn check_screen_active() -> bool {
let logo_image = screen_shot(Some(LOGO));
let data = logo_image.to_png(Some(Compression::Default)).expect("image to png failed");
let active_logo = ImageReader::open("./resources/pokemmo/image/logo_active.png").expect("read active logo image failed").decode().expect("decode image failed");
let active_logo_data = active_logo.as_bytes().to_vec();
let size = data.len();
let mut dis = 0_isize;
for i in 0..size {
dis += active_logo_data[i.clone()].clone() as isize - data[i].clone() as isize;
}
println!("dis : {}", dis);
return dis <= 5000;
}
pub fn read_area(area: Area) -> String {
let psm = area.psm.clone();
let image = screen_shot(Some(area));
let image_data = image.rgba().clone();
let image_width = image.width();
let image_height = image.height();
let dy_image = DynamicImage::from(RgbaImage::from_vec(image_width, image_height, image_data).unwrap());
let text = find_string_in_image(&dy_image, psm).to_lowercase();
return text;
}
pub fn read_group_5() -> Vec<String> {
let mut result = Vec::new();
result.push(read_area(GROUP_5_1));
result.push(read_area(GROUP_5_2));
result.push(read_area(GROUP_5_3));
result.push(read_area(GROUP_5_4));
result.push(read_area(GROUP_5_5));
return result;
}
pub fn get_choose_btn() -> Option<usize> {
let mut btn_list = Vec::new();
btn_list.push(screen_shot(Some(BUTTON_HL_1)));
btn_list.push(screen_shot(Some(BUTTON_HL_2)));
btn_list.push(screen_shot(Some(BUTTON_HL_3)));
btn_list.push(screen_shot(Some(BUTTON_HL_4)));
let mut y_max = 0_f32;
let mut max_index = None;
for index in 0..4 {
let image = &mut btn_list[index];
let data = image.rgba();
let size = data.len();
let pixel_size = size / 4;
let mut r_total = 0_usize;
let mut g_total = 0_usize;
let mut b_total = 0_usize;
for i in 0..pixel_size {
r_total += (data[i.clone() * 4].clone() as usize);
g_total += (data[i.clone() * 4 + 1].clone() as usize);
b_total += (data[i.clone() * 4 + 2].clone() as usize);
}
let r_avg = r_total / pixel_size;
let g_avg = g_total / pixel_size;
let b_avg = b_total / pixel_size;
let r1 = r_avg as f32 / 255_f32;
let g1 = g_avg as f32 / 255_f32;
let b1 = b_avg as f32 / 255_f32;
let max = r1.max(g1).max(b1);
let k = 1_f32 - max;
let y = (1_f32 - b1 - k) / (1_f32 - k);
if y > y_max && y > 0.4_f32 {
y_max = y;
max_index = Some(index);
}
}
return max_index;
}
}