auto search shiny done.
This commit is contained in:
parent
ea08b62096
commit
87ca8c6ec8
|
@ -241,6 +241,27 @@ dependencies = [
|
||||||
"windows",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
|
||||||
|
dependencies = [
|
||||||
|
"errno-dragonfly",
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno-dragonfly"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "exr"
|
name = "exr"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
|
@ -257,6 +278,12 @@ dependencies = [
|
||||||
"zune-inflate",
|
"zune-inflate",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fdeflate"
|
name = "fdeflate"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -400,6 +427,12 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lebe"
|
name = "lebe"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
@ -422,6 +455,12 @@ dependencies = [
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.10"
|
version = "0.4.10"
|
||||||
|
@ -434,9 +473,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.19"
|
version = "0.4.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "malloc_buf"
|
name = "malloc_buf"
|
||||||
|
@ -500,7 +539,11 @@ dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"enigo",
|
"enigo",
|
||||||
"image",
|
"image",
|
||||||
|
"log",
|
||||||
|
"rand",
|
||||||
|
"rusty-tesseract",
|
||||||
"screenshots",
|
"screenshots",
|
||||||
|
"simple-logging",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -576,7 +619,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall 0.3.5",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
@ -626,6 +669,12 @@ dependencies = [
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.66"
|
version = "1.0.66"
|
||||||
|
@ -662,6 +711,36 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
|
@ -684,6 +763,12 @@ dependencies = [
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.1.57"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -693,6 +778,32 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.4.0",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusty-tesseract"
|
||||||
|
version = "1.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af2176026d24dbb67968571c7d464d287934820490ece864e17b88d2e5e3eee8"
|
||||||
|
dependencies = [
|
||||||
|
"image",
|
||||||
|
"subprocess",
|
||||||
|
"substring",
|
||||||
|
"tempfile",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -753,6 +864,17 @@ version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simple-logging"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b00d48e85675326bb182a2286ea7c1a0b264333ae10f27a937a72be08628b542"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"thread-id",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
@ -768,6 +890,25 @@ dependencies = [
|
||||||
"lock_api",
|
"lock_api",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subprocess"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "substring"
|
||||||
|
version = "1.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.28"
|
version = "2.0.28"
|
||||||
|
@ -779,6 +920,50 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"fastrand",
|
||||||
|
"redox_syscall 0.3.5",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread-id"
|
||||||
|
version = "3.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"redox_syscall 0.1.57",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiff"
|
name = "tiff"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -10,10 +10,10 @@ edition = "2021"
|
||||||
|
|
||||||
default = ["pokemmo"]
|
default = ["pokemmo"]
|
||||||
|
|
||||||
pokemmo = ["screen","ocr","joystick","dep:image","pokemon","detector"]
|
pokemmo = ["screen", "ocr", "joystick", "dep:image", "pokemon", "detector"]
|
||||||
screen = ["dep:screenshots"]
|
screen = ["dep:screenshots"]
|
||||||
ocr = []
|
ocr = ["dep:rusty-tesseract", "dep:image"]
|
||||||
joystick = ["dep:enigo"]
|
joystick = ["dep:enigo","dep:rand"]
|
||||||
pokemon = []
|
pokemon = []
|
||||||
detector = ["dep:crossterm"]
|
detector = ["dep:crossterm"]
|
||||||
|
|
||||||
|
@ -26,5 +26,8 @@ path = "src/lib.rs"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
enigo = { version = "0.1.2", optional = true }
|
enigo = { version = "0.1.2", optional = true }
|
||||||
screenshots = { version = "0.7.0", optional = true }
|
screenshots = { version = "0.7.0", optional = true }
|
||||||
image = {version = "0.24.6", optional = true}
|
image = { version = "0.24.6", optional = true }
|
||||||
crossterm = {version = "0.27.0", optional = true}
|
crossterm = { version = "0.27.0", optional = true }
|
||||||
|
rusty-tesseract = { version = "1.1.7", optional = true }
|
||||||
|
rand = { version = "0.8.5", optional = true }
|
||||||
|
simple-logging = {version = "2.0.2"}
|
|
@ -0,0 +1,58 @@
|
||||||
|
#[cfg(feature = "joystick")]
|
||||||
|
pub(crate) mod joystick{
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
use enigo::{Enigo, Key, KeyboardControllable};
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
pub enum MoveMode{
|
||||||
|
// 横向
|
||||||
|
HORIZONTAL,
|
||||||
|
// 纵向
|
||||||
|
PORTRAIT,
|
||||||
|
// 随机
|
||||||
|
RANDOM,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MoveMode {
|
||||||
|
pub fn to_key_list(&self) -> Vec<Key>{
|
||||||
|
return match self {
|
||||||
|
MoveMode::HORIZONTAL => vec![Key::Layout('j'),Key::Layout('l')],
|
||||||
|
MoveMode::PORTRAIT => vec![Key::UpArrow,Key::DownArrow],
|
||||||
|
MoveMode:: RANDOM => vec![Key::LeftArrow,Key::RightArrow,Key::UpArrow,Key::DownArrow],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub(crate) fn move_once_by_mode(road : &MoveMode, index : usize){
|
||||||
|
let mut enigo = Enigo::new();
|
||||||
|
let moves = road.to_key_list();
|
||||||
|
let move_index = index % moves.len();
|
||||||
|
let move_key = moves[move_index];
|
||||||
|
long_press(enigo,move_key,1000,500);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn once_press(mut enigo:Enigo, key: Key){
|
||||||
|
enigo.key_click(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn quick_press(key: Key){
|
||||||
|
let mut enigo = Enigo::new();
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
enigo.key_down(key);
|
||||||
|
thread::sleep(Duration::from_millis(rng.gen_range(0 .. 20)));
|
||||||
|
enigo.key_up(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn long_press(mut enigo:Enigo, key: Key, est_time: isize, random_time: isize){
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
enigo.key_down(key);
|
||||||
|
let act = est_time + rng.gen_range((-random_time .. random_time));
|
||||||
|
thread::sleep(Duration::from_millis(act as u64));
|
||||||
|
enigo.key_up(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::joystick::joystick::joystick::{move_once_by_mode, MoveMode};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_move() {
|
||||||
|
let mut count = 0;
|
||||||
|
let mode = MoveMode::HORIZONTAL;
|
||||||
|
while count < 100 {
|
||||||
|
move_once_by_mode(&mode, 0);
|
||||||
|
count = count + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod joystick;
|
||||||
|
pub mod joystick_test;
|
|
@ -3,3 +3,4 @@ pub(crate) mod joystick;
|
||||||
pub(crate) mod pokemmo;
|
pub(crate) mod pokemmo;
|
||||||
pub(crate) mod pokemon;
|
pub(crate) mod pokemon;
|
||||||
pub(crate) mod detector;
|
pub(crate) mod detector;
|
||||||
|
pub(crate) mod ocr;
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub(crate) mod ocr;
|
||||||
|
mod ocr_test;
|
|
@ -0,0 +1,65 @@
|
||||||
|
#[cfg(feature = "ocr")]
|
||||||
|
pub(crate) mod ocr {
|
||||||
|
use std::error::Error;
|
||||||
|
use image::DynamicImage;
|
||||||
|
use rusty_tesseract::{Args, Image};
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
OEM 解释
|
||||||
|
0 仅旧版引擎
|
||||||
|
1 仅神经网络 LSTM 引擎
|
||||||
|
2 个旧版 + LSTM 引擎
|
||||||
|
3 默认,基于可用的内容
|
||||||
|
|
||||||
|
|
||||||
|
PSM 解释 :
|
||||||
|
0 仅方向和脚本检测 (OSD)。
|
||||||
|
1 使用 OSD 自动页面分割。
|
||||||
|
2 自动页面分割,但没有 OSD 或 OCR。 (未实现)
|
||||||
|
3 全自动页面分割,但无OSD。 (默认)
|
||||||
|
4 假设有一列大小可变的文本。
|
||||||
|
5 假设有一个统一的垂直对齐文本块。
|
||||||
|
6 假设有一个统一的文本块。
|
||||||
|
7 将图像视为单个文本行。
|
||||||
|
8 将图像视为单个单词。
|
||||||
|
9 将图像视为圆圈中的单个单词。
|
||||||
|
10 将图像视为单个字符。
|
||||||
|
11 稀疏文本。 查找尽可能多的文本(不按特定顺序排列)。
|
||||||
|
12 带 OSD 的稀疏文本。
|
||||||
|
13 原始线。 将图像视为单个文本行,
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub(crate) fn find_string_in_image(image: &DynamicImage, psm:i32) -> String {
|
||||||
|
let img = Image::from_dynamic_image(image).expect("from image failed");
|
||||||
|
let mut args = Args {
|
||||||
|
lang: "chi_sim".to_string(),
|
||||||
|
config_variables: Default::default(),
|
||||||
|
dpi: Some(300),
|
||||||
|
psm: Some(psm),
|
||||||
|
oem: Some(3),
|
||||||
|
};
|
||||||
|
let output = rusty_tesseract::image_to_string(&img, &args).expect("image to string failed");
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub(crate) fn find_text_in_image(key_words: &Vec<String>, image: &DynamicImage) -> bool {
|
||||||
|
let img = Image::from_dynamic_image(image).expect("from image failed");
|
||||||
|
let mut args = Args {
|
||||||
|
lang: "chi_sim".to_string(),
|
||||||
|
config_variables: Default::default(),
|
||||||
|
dpi: Some(600),
|
||||||
|
psm: Some(6),
|
||||||
|
oem: Some(3),
|
||||||
|
};
|
||||||
|
let output = rusty_tesseract::image_to_string(&img, &args).expect("image to string failed");
|
||||||
|
for word in key_words{
|
||||||
|
if output.contains(word){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use image::io::Reader;
|
||||||
|
use rusty_tesseract::{Args, Image};
|
||||||
|
use crate::ocr::ocr::ocr::find_text_in_image;
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ocr_image() {
|
||||||
|
println!("ocr !");
|
||||||
|
|
||||||
|
// let img = Image::from_path("test/image/group_5.png").expect("image not found");
|
||||||
|
let img = Image::from_path("test/image/sb.png").expect("image not found");
|
||||||
|
let mut args = Args {
|
||||||
|
lang: "chi_sim".to_string(),
|
||||||
|
config_variables: Default::default(),
|
||||||
|
dpi: Some(300),
|
||||||
|
psm: Some(1),
|
||||||
|
oem: Some(3),
|
||||||
|
};
|
||||||
|
|
||||||
|
// string output
|
||||||
|
let output = rusty_tesseract::image_to_string(&img, &args).expect("ocr error!");
|
||||||
|
println!("The String output is: {:?}", output);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ocr_dynamic_image() {
|
||||||
|
let dynamic_image = Reader::open("test/image/1.png")
|
||||||
|
.unwrap()
|
||||||
|
.decode()
|
||||||
|
.unwrap();
|
||||||
|
let key_words = vec!["头目".to_string(),"白银山".to_string()];
|
||||||
|
let has_word = find_text_in_image(&key_words,&dynamic_image);
|
||||||
|
|
||||||
|
println!("含有关键词:{}",has_word);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -7,25 +7,142 @@ pub mod pokemmo_const_value{
|
||||||
right: 80,
|
right: 80,
|
||||||
top: 0,
|
top: 0,
|
||||||
bottom: 20,
|
bottom: 20,
|
||||||
|
psm : 3,
|
||||||
};
|
};
|
||||||
pub(crate) const MAP_CITY: Area = Area{
|
pub(crate) const MAP_CITY: Area = Area{
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 250,
|
right: 250,
|
||||||
top: 24,
|
top: 24,
|
||||||
bottom: 55,
|
bottom: 55,
|
||||||
|
psm : 7,
|
||||||
};
|
};
|
||||||
pub(crate) const SHORTCUT_KEY_1: Area = Area{
|
pub(crate) const SHORTCUT_KEY_1: Area = Area{
|
||||||
left: 255,
|
left: 255,
|
||||||
right: 298,
|
right: 298,
|
||||||
top: 28,
|
top: 28,
|
||||||
bottom: 70,
|
bottom: 70,
|
||||||
|
psm : 8,
|
||||||
};
|
};
|
||||||
pub(crate) const SHORTCUT_KEY_5: Area = Area{
|
pub(crate) const SHORTCUT_KEY_5: Area = Area{
|
||||||
left: 445,
|
left: 445,
|
||||||
right: 485,
|
right: 485,
|
||||||
top: 28,
|
top: 28,
|
||||||
bottom: 70,
|
bottom: 70,
|
||||||
|
psm : 8,
|
||||||
};
|
};
|
||||||
|
pub(crate) const TEXT_AREA: Area = Area{
|
||||||
|
left: 0,
|
||||||
|
right: 800,
|
||||||
|
top: 1020,
|
||||||
|
bottom: 1340,
|
||||||
|
psm : 6,
|
||||||
|
};
|
||||||
|
// 战斗对话狂
|
||||||
|
pub(crate) const TEMP_BATTLE_TEXT_AREA: Area = Area{
|
||||||
|
left: 400,
|
||||||
|
right: 1100,
|
||||||
|
top: 850,
|
||||||
|
bottom: 1020,
|
||||||
|
psm : 6,
|
||||||
|
};
|
||||||
|
pub(crate) const LAST_TEXT_AREA: Area = Area{
|
||||||
|
left: 0,
|
||||||
|
right: 800,
|
||||||
|
top: 1295,
|
||||||
|
bottom: 1340,
|
||||||
|
psm : 7,
|
||||||
|
};
|
||||||
|
pub(crate) const SINGLE_BATTLE: Area = Area{
|
||||||
|
left: 400,
|
||||||
|
right: 800,
|
||||||
|
top: 180,
|
||||||
|
bottom: 260,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
pub(crate) const GROUP_5_1: Area = Area{
|
||||||
|
left: 700,
|
||||||
|
right: 1050,
|
||||||
|
top: 90,
|
||||||
|
bottom: 148,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
pub(crate) const GROUP_5_2: Area = Area{
|
||||||
|
left: 1100,
|
||||||
|
right: 1400,
|
||||||
|
top: 90,
|
||||||
|
bottom: 148,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
pub(crate) const GROUP_5_3: Area = Area{
|
||||||
|
left: 1500,
|
||||||
|
right: 1800,
|
||||||
|
top: 90,
|
||||||
|
bottom: 148,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
pub(crate) const GROUP_5_4: Area = Area{
|
||||||
|
left: 740,
|
||||||
|
right: 1050,
|
||||||
|
top: 170,
|
||||||
|
bottom: 210,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
pub(crate) const GROUP_5_5: Area = Area{
|
||||||
|
left: 1500,
|
||||||
|
right: 1800,
|
||||||
|
top: 170,
|
||||||
|
bottom: 210,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) const BUTTON_HL_1: Area = Area{
|
||||||
|
left: 392,
|
||||||
|
right: 406,
|
||||||
|
top: 863,
|
||||||
|
bottom: 878,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
pub(crate) const BUTTON_HL_2: Area = Area{
|
||||||
|
left: 708,
|
||||||
|
right: 722,
|
||||||
|
top: 863,
|
||||||
|
bottom: 878,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
pub(crate) const BUTTON_HL_3: Area = Area{
|
||||||
|
left: 392,
|
||||||
|
right: 406,
|
||||||
|
top: 942,
|
||||||
|
bottom: 957,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
pub(crate) const BUTTON_HL_4: Area = Area{
|
||||||
|
left: 708,
|
||||||
|
right: 722,
|
||||||
|
top: 942,
|
||||||
|
bottom: 957,
|
||||||
|
psm : 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum PokemmoStatus {
|
||||||
|
// 遇见闪光
|
||||||
|
MeetShiny,
|
||||||
|
// 无状态
|
||||||
|
Free,
|
||||||
|
// 加载遇怪动画
|
||||||
|
LoadBattle,
|
||||||
|
// 遇怪状态
|
||||||
|
InBattle,
|
||||||
|
// 逃跑中
|
||||||
|
Running,
|
||||||
|
// 检查逃跑成功
|
||||||
|
CheckRun,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,233 @@
|
||||||
#[cfg(feature = "pokemmo")]
|
#[cfg(feature = "pokemmo")]
|
||||||
pub mod pokemmo{
|
pub mod pokemmo {
|
||||||
use screenshots::Compression;
|
use std::thread;
|
||||||
use crate::pokemmo::const_value::pokemmo_const_value::LOGO;
|
use std::time::Duration;
|
||||||
use crate::screen::screen::screen::{screen_shot};
|
|
||||||
|
use enigo::Key;
|
||||||
|
use enigo::Key::{N, V};
|
||||||
|
use image::{DynamicImage, RgbaImage};
|
||||||
use image::io::Reader as ImageReader;
|
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, MeetShiny, 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::MeetShiny => {
|
||||||
|
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("野生") || text.contains("派出") {
|
||||||
|
info!("遇怪:{}.",text);
|
||||||
|
meet_pokemmo = text.clone();
|
||||||
|
status = LoadBattle;
|
||||||
|
}else {
|
||||||
|
let temp_battle = read_area(TEMP_BATTLE_TEXT_AREA);
|
||||||
|
if temp_battle.contains("战斗") || temp_battle.contains("逃跑"){
|
||||||
|
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("野生")).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("怪群") {
|
||||||
|
info!("遇见怪群");
|
||||||
|
let five_names = read_group_5();
|
||||||
|
for name in five_names {
|
||||||
|
for key_word in key_words {
|
||||||
|
if name.contains(key_word) {
|
||||||
|
status = MeetShiny;
|
||||||
|
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 = MeetShiny;
|
||||||
|
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("成功")
|
||||||
|
&& !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("成功") || last_word.contains("逃跑") {
|
||||||
|
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{
|
pub(crate) fn check_screen_active() -> bool {
|
||||||
|
|
||||||
let logo_image = screen_shot(Some(LOGO));
|
let logo_image = screen_shot(Some(LOGO));
|
||||||
let data= logo_image.to_png(Some(Compression::Default)).expect("image to png failed");
|
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 = 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 active_logo_data = active_logo.as_bytes().to_vec();
|
||||||
|
|
||||||
let size = data.len();
|
let size = data.len();
|
||||||
let mut dis = 0_isize;
|
let mut dis = 0_isize;
|
||||||
for i in 0 .. size{
|
for i in 0..size {
|
||||||
dis += active_logo_data[i].clone() as isize - data[i].clone() as isize;
|
dis += active_logo_data[i.clone()].clone() as isize - data[i].clone() as isize;
|
||||||
}
|
}
|
||||||
println!("dis : {}",dis);
|
println!("dis : {}", dis);
|
||||||
|
|
||||||
return dis <= 5000;
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,52 +3,81 @@ mod tests {
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use image::io::Reader as ImageReader;
|
use image::io::Reader as ImageReader;
|
||||||
use crate::pokemmo::const_value::pokemmo_const_value::{LOGO, MAP_CITY, SHORTCUT_KEY_1, SHORTCUT_KEY_5};
|
use log::LevelFilter;
|
||||||
use crate::pokemmo::pokemmo::pokemmo::check_screen_active;
|
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, MAP_CITY, SHORTCUT_KEY_1, SHORTCUT_KEY_5, SINGLE_BATTLE, TEMP_BATTLE_TEXT_AREA, TEXT_AREA};
|
||||||
|
use crate::pokemmo::pokemmo::pokemmo::{check_screen_active, get_choose_btn, get_last_string, read_area, read_group_5, single_meet_shiny};
|
||||||
use crate::screen::screen::screen::{print_image, screen_shot};
|
use crate::screen::screen::screen::{print_image, screen_shot};
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn print_logo() {
|
fn try_meet_shiny(){
|
||||||
sleep(Duration::from_secs(1));
|
simple_logging::log_to_file("./test/log/meet_shiny.log",LevelFilter::Info).expect("set log failed");
|
||||||
|
|
||||||
let logo_image = screen_shot(Some(LOGO));
|
let key_words = vec![
|
||||||
print_image(logo_image, "logo".to_string());
|
"闪".to_string(),
|
||||||
|
"光".to_string(),
|
||||||
|
];
|
||||||
|
single_meet_shiny(&key_words);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let active = check_screen_active();
|
#[test]
|
||||||
println!("main screen active : {}", active);
|
fn print_shortcut() {
|
||||||
|
let text = screen_shot(Some(TEMP_BATTLE_TEXT_AREA));
|
||||||
|
print_image(text, "temp_battle_text".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn print_city() {
|
fn print_group_5() {
|
||||||
sleep(Duration::from_secs(1));
|
let group_5_1 = screen_shot(Some(GROUP_5_1));
|
||||||
|
print_image(group_5_1, "group_5_1".to_string());
|
||||||
|
let group_5_2 = screen_shot(Some(GROUP_5_2));
|
||||||
|
print_image(group_5_2, "group_5_2".to_string());
|
||||||
|
let group_5_3 = screen_shot(Some(GROUP_5_3));
|
||||||
|
print_image(group_5_3, "group_5_3".to_string());
|
||||||
|
let group_5_4 = screen_shot(Some(GROUP_5_4));
|
||||||
|
print_image(group_5_4, "group_5_4".to_string());
|
||||||
|
let group_5_5 = screen_shot(Some(GROUP_5_5));
|
||||||
|
print_image(group_5_5, "group_5_5".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn print_button() {
|
||||||
|
let btn_hl_1 = screen_shot(Some(BUTTON_HL_1));
|
||||||
|
print_image(btn_hl_1, "btn_hl_1".to_string());
|
||||||
|
let btn_hl_2 = screen_shot(Some(BUTTON_HL_2));
|
||||||
|
print_image(btn_hl_2, "btn_hl_2".to_string());
|
||||||
|
let btn_hl_3 = screen_shot(Some(BUTTON_HL_3));
|
||||||
|
print_image(btn_hl_3, "btn_hl_3".to_string());
|
||||||
|
let btn_hl_4 = screen_shot(Some(BUTTON_HL_4));
|
||||||
|
print_image(btn_hl_4, "btn_hl_4".to_string());
|
||||||
|
|
||||||
let logo_image = screen_shot(Some(MAP_CITY));
|
|
||||||
print_image(logo_image, "city".to_string());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn print_shortcut_key_1() {
|
fn find_text() {
|
||||||
sleep(Duration::from_secs(1));
|
let text = read_area(TEMP_BATTLE_TEXT_AREA);
|
||||||
|
println!("text in image: {}",text);
|
||||||
let logo_image = screen_shot(Some(SHORTCUT_KEY_1));
|
|
||||||
print_image(logo_image, "key_1".to_string());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn print_shortcut_key_5() {
|
fn get_active_btn() {
|
||||||
sleep(Duration::from_secs(1));
|
let index_op = get_choose_btn();
|
||||||
|
if index_op.is_some(){
|
||||||
let logo_image = screen_shot(Some(SHORTCUT_KEY_5));
|
println!("激活索引:{}",index_op.unwrap());
|
||||||
print_image(logo_image, "key_5".to_string());
|
}else {
|
||||||
|
println!("无激活索引");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compare_logo() {
|
fn compare_logo() {
|
||||||
|
|
||||||
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 = 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 active_logo_data = active_logo.as_bytes().to_vec();
|
||||||
|
|
||||||
|
@ -59,11 +88,8 @@ mod tests {
|
||||||
|
|
||||||
let mut dis = 0_isize;
|
let mut dis = 0_isize;
|
||||||
for i in 0 .. size{
|
for i in 0 .. size{
|
||||||
dis += na_logo_data[i].clone() as isize - active_logo_data[i].clone() as isize;
|
dis += na_logo_data[i.clone()].clone() as isize - active_logo_data[i.clone()].clone() as isize;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("dis = {}",dis);
|
println!("dis = {}",dis);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,147 @@
|
||||||
#[cfg(feature = "pokemon")]
|
#[cfg(feature = "pokemon")]
|
||||||
pub(crate) mod pokemon{
|
pub(crate) mod pokemon {
|
||||||
|
pub enum PokeType {
|
||||||
|
Normal,
|
||||||
|
Fighting,
|
||||||
|
Flying,
|
||||||
|
Poison,
|
||||||
|
Ground,
|
||||||
|
Rock,
|
||||||
|
Bug,
|
||||||
|
Ghost,
|
||||||
|
Steel,
|
||||||
|
File,
|
||||||
|
Water,
|
||||||
|
Grass,
|
||||||
|
Electric,
|
||||||
|
Psychic,
|
||||||
|
Ice,
|
||||||
|
Dragon,
|
||||||
|
Dark,
|
||||||
|
Fairy,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Pokemon {
|
||||||
|
pub(crate) dex: PokeDex,
|
||||||
|
pub(crate) moves: Vec<MoveCategory>,
|
||||||
|
pub(crate) lv: u32,
|
||||||
|
pub(crate) stat: Stat,
|
||||||
|
pub(crate) status: StatusChange,
|
||||||
|
pub(crate) nature: Nature
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PokeDex {
|
||||||
|
pub(crate) no: u32,
|
||||||
|
pub(crate) fir_type: PokeType,
|
||||||
|
pub(crate) sec_type: Option<PokeType>,
|
||||||
|
pub(crate) iv: Iv,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Iv {
|
||||||
|
pub(crate) hp: u32,
|
||||||
|
pub(crate) attack: u32,
|
||||||
|
pub(crate) defense: u32,
|
||||||
|
pub(crate) sp_atk: u32,
|
||||||
|
pub(crate) sp_def: u32,
|
||||||
|
pub(crate) speed: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Ev {
|
||||||
|
pub(crate) hp: u32,
|
||||||
|
pub(crate) attack: u32,
|
||||||
|
pub(crate) defense: u32,
|
||||||
|
pub(crate) sp_atk: u32,
|
||||||
|
pub(crate) sp_def: u32,
|
||||||
|
pub(crate) speed: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Stat {
|
||||||
|
pub(crate) hp: u32,
|
||||||
|
pub(crate) attack: u32,
|
||||||
|
pub(crate) defense: u32,
|
||||||
|
pub(crate) sp_atk: u32,
|
||||||
|
pub(crate) sp_def: u32,
|
||||||
|
pub(crate) speed: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StatusChange {
|
||||||
|
pub(crate) attack: i32,
|
||||||
|
pub(crate) defense: i32,
|
||||||
|
pub(crate) sp_atk: i32,
|
||||||
|
pub(crate) sp_def: i32,
|
||||||
|
pub(crate) speed: i32,
|
||||||
|
pub(crate) accuracy: i32,
|
||||||
|
pub(crate) evasion: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MoveCategory {
|
||||||
|
Physical,
|
||||||
|
Special,
|
||||||
|
Status,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Move {
|
||||||
|
pub(crate) cat: MoveCategory,
|
||||||
|
pub(crate) value: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Nature {
|
||||||
|
Hardy,
|
||||||
|
Lonely,
|
||||||
|
Brave,
|
||||||
|
Adamant,
|
||||||
|
Naughty,
|
||||||
|
Bold,
|
||||||
|
Docile,
|
||||||
|
Relaxed,
|
||||||
|
Impish,
|
||||||
|
Lax,
|
||||||
|
Timid,
|
||||||
|
Hasty,
|
||||||
|
Serious,
|
||||||
|
Jolly,
|
||||||
|
Naive,
|
||||||
|
Modest,
|
||||||
|
Mild,
|
||||||
|
Quiet,
|
||||||
|
Bashful,
|
||||||
|
Rash,
|
||||||
|
Calm,
|
||||||
|
Gentle,
|
||||||
|
Sassy,
|
||||||
|
Careful,
|
||||||
|
Quirky,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Nature {
|
||||||
|
pub fn influence(&self) -> (f32, f32, f32, f32, f32) {
|
||||||
|
return match self {
|
||||||
|
Hardy => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||||
|
Lonely => (1.1_f32, 0.9_f32, 0_f32, 0_f32, 0_f32),
|
||||||
|
Brave => (1.1_f32, 0_f32, 0_f32, 0_f32, 0.9_f32),
|
||||||
|
Adamant => (1.1_f32, 0_f32, 0.9_f32, 0_f32, 0_f32),
|
||||||
|
Naughty => (1.1_f32, 0_f32, 0_f32, 0.9_f32, 0_f32),
|
||||||
|
Bold => (0.9_f32, 1.1_f32, 0_f32, 0_f32, 0_f32),
|
||||||
|
Docile => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||||
|
Relaxed => (0_f32, 1.1_f32, 0_f32, 0_f32, 0.9_f32),
|
||||||
|
Impish => (0_f32, 1.1_f32, 0.9_f32, 0_f32, 0_f32),
|
||||||
|
Lax => (0_f32, 1.1_f32, 0_f32, 0.9_f32, 0_f32),
|
||||||
|
Timid => (0.9_f32, 0_f32, 0_f32, 0_f32, 1.1_f32),
|
||||||
|
Hasty => (0_f32, 0.9_f32, 0_f32, 0_f32, 1.1_f32),
|
||||||
|
Serious => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||||
|
Jolly => (0_f32, 0_f32, 0.9_f32, 0_f32, 1.1_f32),
|
||||||
|
Naive => (0_f32, 0_f32, 0_f32, 0.9_f32, 1.1_f32),
|
||||||
|
Modest => (0.9_f32, 0_f32, 1.1_f32, 0_f32, 0_f32),
|
||||||
|
Mild => (0_f32, 0.9_f32, 1.1_f32, 0_f32, 0_f32),
|
||||||
|
Quiet => (0_f32, 0_f32, 1.1_f32, 0_f32, 0.9_f32),
|
||||||
|
Bashful => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||||
|
Rash => (0_f32, 0_f32, 1.1_f32, 0.9_f32, 0_f32),
|
||||||
|
Calm => (0.9_f32, 0_f32, 0_f32, 1.1_f32, 0_f32),
|
||||||
|
Gentle => (0_f32, 0.9_f32, 0_f32, 1.1_f32, 0_f32),
|
||||||
|
Sassy => (0_f32, 0_f32, 0_f32, 1.1_f32, 0.9_f32),
|
||||||
|
Careful => (0_f32, 0_f32, 0.9_f32, 1.1_f32, 0_f32),
|
||||||
|
Quirky => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,8 +9,10 @@ pub mod screen {
|
||||||
pub right: i32,
|
pub right: i32,
|
||||||
pub top: i32,
|
pub top: i32,
|
||||||
pub bottom: i32,
|
pub bottom: i32,
|
||||||
|
pub psm : i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn screen_shot(area: Option<Area>) -> Image {
|
pub fn screen_shot(area: Option<Area>) -> Image {
|
||||||
let main_screen_list: Vec<Screen> = Screen::all().expect("get all screen failed").into_iter().filter(|x| x.display_info.is_primary).collect();
|
let main_screen_list: Vec<Screen> = Screen::all().expect("get all screen failed").into_iter().filter(|x| x.display_info.is_primary).collect();
|
||||||
let main_screen = main_screen_list.first().expect("get main screen failed");
|
let main_screen = main_screen_list.first().expect("get main screen failed");
|
||||||
|
@ -25,12 +27,9 @@ pub mod screen {
|
||||||
return image
|
return image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn print_image(image: Image,file_name : String){
|
pub fn print_image(image: Image,file_name : String){
|
||||||
fs::write(format!("test/image/{}.png", file_name), image.to_png(Some(Compression::Default)).expect("image to png failed")).unwrap();
|
fs::write(format!("test/image/{}.png", file_name), image.to_png(Some(Compression::Default)).expect("image to png failed")).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -10,12 +10,10 @@ mod tests {
|
||||||
right: 300,
|
right: 300,
|
||||||
top: 0,
|
top: 0,
|
||||||
bottom: 300,
|
bottom: 300,
|
||||||
|
psm: 3,
|
||||||
};
|
};
|
||||||
let image = screen_shot(Some(area));
|
let image = screen_shot(Some(area));
|
||||||
|
|
||||||
print_image(image,"abc".to_string());
|
print_image(image,"abc".to_string());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue