-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allow sending messages for different chats (j,k,l)
- Loading branch information
1 parent
f2d94ce
commit 81d70b3
Showing
6 changed files
with
304 additions
and
249 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,29 @@ | ||
# Battlefield anti-idle | ||
This tool will prevent you from getting kicked for idle for Battlefield 4, 1, 5 and 2042, you only have to run it and it will work even if the game is minimized. | ||
It can also send messages on specified times based on what you set in the config. | ||
|
||
download it here: https://github.com/community-network/battlefield-anti-idle/releases/latest | ||
|
||
Config file | ||
```bash | ||
# It will autogenerate one of these files when you run the script when it doesn't exist already. | ||
|
||
# It will send messages based on timeout when set to true | ||
send_messages = false | ||
# Message it will send | ||
message = 'Join our discord, we are always recruiting: discord.gg/BoB' | ||
# When it will start sending messages, based on the UTC timezone | ||
message_start_time_utc = '12:00' | ||
# When it will stop sending messages, based on the UTC timezone | ||
message_stop_time_utc = '23:00' | ||
# Timeout used when sending messages | ||
message_timeout_mins = 8 | ||
``` | ||
# Battlefield anti-idle | ||
|
||
This tool will prevent you from getting kicked for idle for Battlefield 4, 1, 5 and 2042, you only have to run it and it will work even if the game is minimized. | ||
It can also send messages on specified times based on what you set in the config. | ||
|
||
download it here: https://github.com/community-network/battlefield-anti-idle/releases/latest | ||
|
||
Config file | ||
|
||
```bash | ||
# It will autogenerate one of these files when you run the script when it doesn't exist already. | ||
|
||
# It will send messages based on timeout when set to true | ||
send_messages = false | ||
# Message it will send | ||
messages = [ | ||
'test1', | ||
'test2', | ||
'test3', | ||
] | ||
# In which chat it has to send the messages (can be 'Public', 'Team' or 'Squad') | ||
chat_type = 'Public' | ||
# When it will start sending messages, based on the UTC timezone | ||
message_start_time_utc = '12:00' | ||
# When it will stop sending messages, based on the UTC timezone | ||
message_stop_time_utc = '23:00' | ||
# Timeout used when sending messages | ||
message_timeout_mins = 8 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
send_messages = false | ||
message = 'Join our discord, we are always recruiting: discord.gg/BoB' | ||
send_messages = true | ||
messages = [ | ||
'test1', | ||
'test2', | ||
'test3', | ||
] | ||
chat_type = 'Public' | ||
message_start_time_utc = '12:00' | ||
message_stop_time_utc = '23:00' | ||
message_timeout_mins = 8 | ||
message_timeout_mins = 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,130 +1,156 @@ | ||
use std::ffi::OsStr; | ||
use std::iter::once; | ||
use std::os::windows::prelude::OsStrExt; | ||
use std::ptr; | ||
use std::thread::sleep; | ||
use std::time::Duration; | ||
use winapi::shared::windef::HWND__; | ||
use winapi::um::winuser::{ | ||
FindWindowW, GetForegroundWindow, SendMessageW, SetForegroundWindow, ShowWindow, | ||
}; | ||
|
||
use crate::chars::{char_to_dxcodes, DXCode}; | ||
use crate::{send_keys, structs}; | ||
|
||
fn make_l_param(lo_word: i32, hi_word: i32) -> i32 { | ||
(hi_word << 16) | (lo_word & 0xffff) | ||
} | ||
|
||
pub fn anti_afk(game_name: &str, mut run_once_no_game: bool) -> bool { | ||
let game_info = is_running(game_name); | ||
if game_info.is_running { | ||
unsafe { | ||
let current_forground_window = GetForegroundWindow(); | ||
let l_param = make_l_param(20, 20); | ||
SendMessageW(game_info.game_process, 0x201, 0, l_param as isize); | ||
SendMessageW(game_info.game_process, 0x202, 0, l_param as isize); | ||
SetForegroundWindow(current_forground_window); | ||
// reset no game check | ||
run_once_no_game = true; | ||
} | ||
log::info!("Running anti-idle for {}.", game_name); | ||
} else if run_once_no_game { | ||
log::info!("No game found, idleing..."); | ||
run_once_no_game = false; | ||
} | ||
run_once_no_game | ||
} | ||
|
||
fn message_action(cfg: &structs::SeederConfig) { | ||
unsafe { | ||
send_keys::key_enter(0x24, 50); // J | ||
sleep(Duration::from_secs(3)); | ||
let mut message: Vec<DXCode> = Vec::new(); | ||
for char in cfg.message.chars() { | ||
if let Some(dx) = char_to_dxcodes(char) { | ||
message.push(dx) | ||
} | ||
} | ||
send_keys::send_string(message); | ||
sleep(Duration::from_secs(1)); | ||
send_keys::key_enter(0x1C, 8); // ENTER | ||
sleep(Duration::from_secs(1)); | ||
} | ||
} | ||
|
||
fn bf2042_message_action(cfg: &structs::SeederConfig) { | ||
unsafe { | ||
// println!("Open pause menu"); | ||
send_keys::key_enter(0x01, 80); // ESC | ||
sleep(Duration::from_secs(1)); | ||
// println!("Most left menu"); | ||
send_keys::spam_keys(0x10, 80, 3); // Q | ||
sleep(Duration::from_secs(1)); | ||
// println!("Top of list"); | ||
send_keys::spam_keys(0xD0, 80, 5); // DOWN | ||
sleep(Duration::from_secs(1)); | ||
// println!("from bottom second item"); | ||
send_keys::key_enter(0xC8, 80); // UP | ||
sleep(Duration::from_secs(1)); | ||
// println!("Click!"); | ||
send_keys::key_enter(0x39, 80); // SPACE | ||
sleep(Duration::from_secs(1)); | ||
// println!("Move to top item for broadcast menu!"); | ||
send_keys::spam_keys(0xC8, 80, 5); // UP | ||
sleep(Duration::from_secs(1)); | ||
// println!("broadcast menu"); | ||
send_keys::key_enter(0x39, 80); // SPACE | ||
sleep(Duration::from_secs(1)); | ||
// println!("fill in"); | ||
send_keys::spam_keys(0xC8, 8, 2); // UP | ||
sleep(Duration::from_secs(1)); | ||
// println!("fill mode"); | ||
send_keys::key_enter(0x39, 80); // SPACE | ||
sleep(Duration::from_secs(1)); | ||
let mut message: Vec<DXCode> = Vec::new(); | ||
for char in cfg.message.chars() { | ||
if let Some(dx) = char_to_dxcodes(char) { | ||
message.push(dx) | ||
} | ||
} | ||
send_keys::send_string(message); | ||
sleep(Duration::from_secs(1)); | ||
// println!("done with message"); | ||
send_keys::key_enter(0x1C, 80); // ENTER | ||
sleep(Duration::from_secs(1)); | ||
// println!("Back to spawn screen"); | ||
send_keys::spam_keys(0x01, 8, 3); // ESC | ||
sleep(Duration::from_secs(1)); | ||
} | ||
} | ||
|
||
// https://gist.github.com/dretax/fe37b8baf55bc30e9d63 | ||
pub fn send_message(cfg: &structs::SeederConfig, game_name: &str) { | ||
let game_info = is_running(game_name); | ||
if game_info.is_running { | ||
unsafe { | ||
SetForegroundWindow(game_info.game_process); | ||
ShowWindow(game_info.game_process, 9); | ||
sleep(Duration::from_millis(1808)); | ||
if game_name == "Battlefield™ 2042" { | ||
bf2042_message_action(cfg); | ||
} else { | ||
message_action(cfg); | ||
} | ||
ShowWindow(game_info.game_process, 6); | ||
} | ||
} | ||
} | ||
|
||
pub fn is_running(game_name: &str) -> structs::GameInfo { | ||
unsafe { | ||
let window: Vec<u16> = OsStr::new(game_name).encode_wide().chain(once(0)).collect(); | ||
let window_handle = FindWindowW(std::ptr::null_mut(), window.as_ptr()); | ||
let no_game: *mut HWND__ = ptr::null_mut(); | ||
structs::GameInfo { | ||
is_running: window_handle != no_game, | ||
game_process: window_handle, | ||
} | ||
} | ||
} | ||
use std::ffi::OsStr; | ||
use std::iter::once; | ||
use std::os::windows::prelude::OsStrExt; | ||
use std::ptr; | ||
use std::sync::atomic::{self, AtomicU32}; | ||
use std::sync::Arc; | ||
use std::thread::sleep; | ||
use std::time::Duration; | ||
use winapi::shared::windef::HWND__; | ||
use winapi::um::winuser::{ | ||
FindWindowW, GetForegroundWindow, SendMessageW, SetForegroundWindow, ShowWindow, | ||
}; | ||
|
||
use crate::chars::{char_to_dxcodes, DXCode}; | ||
use crate::{send_keys, structs}; | ||
|
||
fn make_l_param(lo_word: i32, hi_word: i32) -> i32 { | ||
(hi_word << 16) | (lo_word & 0xffff) | ||
} | ||
|
||
pub fn anti_afk(game_name: &str, mut run_once_no_game: bool) -> bool { | ||
let game_info = is_running(game_name); | ||
if game_info.is_running { | ||
unsafe { | ||
let current_forground_window = GetForegroundWindow(); | ||
let l_param = make_l_param(20, 20); | ||
SendMessageW(game_info.game_process, 0x201, 0, l_param as isize); | ||
SendMessageW(game_info.game_process, 0x202, 0, l_param as isize); | ||
SetForegroundWindow(current_forground_window); | ||
// reset no game check | ||
run_once_no_game = true; | ||
} | ||
log::info!("Running anti-idle for {}.", game_name); | ||
} else if run_once_no_game { | ||
log::info!("No game found, idleing..."); | ||
run_once_no_game = false; | ||
} | ||
run_once_no_game | ||
} | ||
|
||
fn message_action(message_to_send: &str, open_chat_key: u16) { | ||
unsafe { | ||
send_keys::key_enter(open_chat_key, 50); // J | ||
sleep(Duration::from_secs(3)); | ||
let mut current_message: Vec<DXCode> = Vec::new(); | ||
for char in message_to_send.chars() { | ||
if let Some(dx) = char_to_dxcodes(char) { | ||
current_message.push(dx) | ||
} | ||
} | ||
send_keys::send_string(current_message); | ||
sleep(Duration::from_secs(1)); | ||
send_keys::key_enter(0x1C, 8); // ENTER | ||
sleep(Duration::from_secs(1)); | ||
} | ||
} | ||
|
||
fn bf2042_message_action(message_to_send: &str) { | ||
unsafe { | ||
// println!("Open pause menu"); | ||
send_keys::key_enter(0x01, 80); // ESC | ||
sleep(Duration::from_secs(1)); | ||
// println!("Most left menu"); | ||
send_keys::spam_keys(0x10, 80, 3); // Q | ||
sleep(Duration::from_secs(1)); | ||
// println!("Top of list"); | ||
send_keys::spam_keys(0xD0, 80, 5); // DOWN | ||
sleep(Duration::from_secs(1)); | ||
// println!("from bottom second item"); | ||
send_keys::key_enter(0xC8, 80); // UP | ||
sleep(Duration::from_secs(1)); | ||
// println!("Click!"); | ||
send_keys::key_enter(0x39, 80); // SPACE | ||
sleep(Duration::from_secs(1)); | ||
// println!("Move to top item for broadcast menu!"); | ||
send_keys::spam_keys(0xC8, 80, 5); // UP | ||
sleep(Duration::from_secs(1)); | ||
// println!("broadcast menu"); | ||
send_keys::key_enter(0x39, 80); // SPACE | ||
sleep(Duration::from_secs(1)); | ||
// println!("fill in"); | ||
send_keys::spam_keys(0xC8, 8, 2); // UP | ||
sleep(Duration::from_secs(1)); | ||
// println!("fill mode"); | ||
send_keys::key_enter(0x39, 80); // SPACE | ||
sleep(Duration::from_secs(1)); | ||
let mut current_message: Vec<DXCode> = Vec::new(); | ||
for char in message_to_send.chars() { | ||
if let Some(dx) = char_to_dxcodes(char) { | ||
current_message.push(dx) | ||
} | ||
} | ||
send_keys::send_string(current_message); | ||
sleep(Duration::from_secs(1)); | ||
// println!("done with message"); | ||
send_keys::key_enter(0x1C, 80); // ENTER | ||
sleep(Duration::from_secs(1)); | ||
// println!("Back to spawn screen"); | ||
send_keys::spam_keys(0x01, 8, 3); // ESC | ||
sleep(Duration::from_secs(1)); | ||
} | ||
} | ||
|
||
// https://gist.github.com/dretax/fe37b8baf55bc30e9d63 | ||
pub fn send_message( | ||
cfg: &structs::SeederConfig, | ||
game_name: &str, | ||
current_message_id: &Arc<AtomicU32>, | ||
) { | ||
let game_info = is_running(game_name); | ||
if game_info.is_running { | ||
let mut message_id = current_message_id.load(atomic::Ordering::Relaxed); | ||
let current_message: &String = &cfg.messages[message_id as usize]; | ||
|
||
unsafe { | ||
SetForegroundWindow(game_info.game_process); | ||
ShowWindow(game_info.game_process, 9); | ||
sleep(Duration::from_millis(1808)); | ||
|
||
match cfg.chat_type { | ||
structs::ChatType::Public => { | ||
if game_name == "Battlefield™ 2042" { | ||
bf2042_message_action(current_message); | ||
} else { | ||
message_action(current_message, 0x24); | ||
} | ||
} | ||
structs::ChatType::Team => message_action(current_message, 0x25), | ||
structs::ChatType::Squad => message_action(current_message, 0x26), | ||
} | ||
|
||
ShowWindow(game_info.game_process, 6); | ||
} | ||
|
||
if message_id + 1 >= cfg.messages.len() as u32 { | ||
message_id = 0; | ||
} else { | ||
message_id += 1; | ||
} | ||
|
||
// save | ||
current_message_id.store(message_id, atomic::Ordering::Relaxed); | ||
} | ||
} | ||
|
||
pub fn is_running(game_name: &str) -> structs::GameInfo { | ||
unsafe { | ||
let window: Vec<u16> = OsStr::new(game_name).encode_wide().chain(once(0)).collect(); | ||
let window_handle = FindWindowW(std::ptr::null_mut(), window.as_ptr()); | ||
let no_game: *mut HWND__ = ptr::null_mut(); | ||
structs::GameInfo { | ||
is_running: window_handle != no_game, | ||
game_process: window_handle, | ||
} | ||
} | ||
} |
Oops, something went wrong.