Skip to content

Commit

Permalink
allow sending messages for different chats (j,k,l)
Browse files Browse the repository at this point in the history
  • Loading branch information
zefanjajobse committed Mar 19, 2023
1 parent f2d94ce commit 81d70b3
Show file tree
Hide file tree
Showing 6 changed files with 304 additions and 249 deletions.
50 changes: 29 additions & 21 deletions Readme.md
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
```
11 changes: 8 additions & 3 deletions config.txt
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
286 changes: 156 additions & 130 deletions src/actions.rs
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,
}
}
}
Loading

0 comments on commit 81d70b3

Please sign in to comment.